首页 > 解决方案 > Stripe IOS 与 Firebase 集成:创建付款意图不起作用

问题描述

我正在使用条纹创建支付流程。我们的后端在 firebase 服务上运行。目前,当我打开 paymentVC 时,我可以选择一个“付款方式”按钮,允许用户输入他们的信用卡信息并将其存储在他们的用户帐户中。我在同一个 paymentVC 上有另一个按钮,称为“下订单”,它应该完成订单或显示一个视图,让用户在下订单之前输入更多信息。但是,这些都不起作用,因为我发送到条带的付款意图被列为不完整,因为“客户尚未输入他们的付款方式”。如何连接这两个事件,以便在发送付款意图时具有该用户的付款方式?

import UIKit
import Stripe
import FirebaseFunctions

class paymentViewController: UIViewController {

    @IBOutlet weak var paymentMethodButton: UIButton!
    @IBOutlet weak var proceedToCheckoutButton: UIButton!

    var paymentContext: STPPaymentContext!

    override func viewDidLoad() {
        super.viewDidLoad()
        setupStripeConfig()
    }

    @IBAction func checkoutButtonClicked(_ sender: Any) {
        paymentContext.requestPayment()
    }

    @IBAction func paymentMethodClicked(_ sender: Any) {
        print("Payment Method Button Clicked")
        paymentContext.presentPaymentOptionsViewController()
    }

    func setupStripeConfig() {
        let config = STPPaymentConfiguration.shared()
        config.requiredBillingAddressFields = .none
        config.requiredShippingAddressFields = .none

        let customerContext = STPCustomerContext(keyProvider: StripeAPI)
        paymentContext = STPPaymentContext(customerContext: customerContext, configuration: config, theme: .default())
        paymentContext.paymentAmount = 1000

        paymentContext.delegate = self
        paymentContext.hostViewController = self
    }
}

extension paymentViewController: STPPaymentContextDelegate {

    func paymentContextDidChange(_ paymentContext: STPPaymentContext) {
        self.paymentMethodButton.titleLabel?.text = paymentContext.selectedPaymentOption?.label
    }


    func paymentContext(_ paymentContext: STPPaymentContext, didFailToLoadWithError error: Error) {
        //When stripeID isn't valid or Ephemeral key could not be retrieved for some reason. Handle this with UIAlert stating error and make user re-enter info
        self.navigationController?.popViewController(animated: true)
    }

    func paymentContext(_ paymentContext: STPPaymentContext, didCreatePaymentResult paymentResult: STPPaymentResult, completion: @escaping STPPaymentStatusBlock) {

        var data = [
            "customer" : _UserService.user.stripe_id
        ]
        //Pull Payment Method
        Functions.functions().httpsCallable("getPaymentMethods").call(data) { (result, err) in
            if err != nil {
                print("Error \(String(describing: err))")
                return
            }

            print(result)
        }


        let idempotency = UUID().uuidString.replacingOccurrences(of: "-", with: "")
        var paymentMethod = paymentContext.selectedPaymentOption

        let dataToSend: [String : Any] = [
            "amount" : 5000,
            "customer" : _UserService.user.stripe_id,
        ]

        Functions.functions().httpsCallable("createPaymentIntent").call(dataToSend) { (result, err) in
            if err != nil {
                print("Error \(String(describing: err))")
                return
            }

            //var paymentParam = STPPaymentIntentParams(clientSecret: result as! String)
            print(result)
        }
    }

    func paymentContext(_ paymentContext: STPPaymentContext, didFinishWith status: STPPaymentStatus, error: Error?) {

    }

}

以及带有我的云功能的 index.js 文件。

const admin = require('firebase-admin');
const express = require('express')
admin.initializeApp();

const functions = require('firebase-functions');
const stripe = require('stripe')("sk_test_____________________________");


// When a user is created, register them with Stripe
exports.createStripeCustomer = functions.auth.user().onCreate(async (user) => {
  const customer = await stripe.customers.create({email: user.email});
  return admin.firestore().collection('stripe_customers').doc(user.uid).set({customer_id: customer.id});
});

exports.createPaymentIntent = functions.https.onCall(async (req, res) => {

  const amount = req.amount;
  const customer = req.customer;
  console.log(customer)

  const paymentIntent = await stripe.paymentIntents.create({
      amount: 1099,
      currency: 'usd',
  });
    const clientSecret = paymentIntent.clientSecret
    console.log(clientSecret)
    return clientSecret
});

exports.getPaymentMethods = functions.https.onCall(async (req, res) => {
  const customer = req.customer;
  const type = "card"

  stripe.paymentMethods.list({customer : customer, type: type}, function(err, paymentMethods) {
    if (err !== null) {
      console.log("ERROR")
    } else {
      return paymentMethods
    }
    return
  })
});

exports.createEphemeralKey = functions.https.onCall(async(data, context) => {
  const stripeVersion = data.stripe_version;
  const customerId = data.customer_id;

  return stripe.ephemeralKeys.create(
    {customer: customerId},
    {stripe_version: stripeVersion}
  ).then((key) => {
    return key
  }).catch((err) => {
    console.log(err)
  })
})

我尝试使用 stripe.paymentMethods.list 调用从某个用户获取所有付款方式,并使用它作为数据传递给付款意图,但这并不奏效。有没有更好的方法来实现这一点?

标签: node.jsswiftfirebasestripe-payments

解决方案


推荐阅读