swift 如何将Apple Pay支付令牌发送到Stripe以完成充值?

r8xiu3jd  于 2023-05-16  发布在  Swift
关注(0)|答案(1)|浏览(213)

我使用SwiftUI。我的代码目前只使用PassKit。它与SwiftUI集成得很好,我能够从Apple Pay获得加密的Payment.Token。我想使用该令牌,并在客户端进行令牌化(根据stripe docs,这是遵守法律的最佳方式),并将其发送到stripe以完成支付。我有问题,以什么API端点调用,以发送和完成所有这一切,同时保持合规。文档只显示使用Stripe SDK,这很难与Swiftui集成。

import PassKit
import Stripe

typealias PaymentCompletionHandler = (Bool) -> Void

class PaymentHandler: NSObject{

static let supportedNetworks: [PKPaymentNetwork] = [
    .amex,
    .masterCard,
    .visa
]

var paymentController: PKPaymentAuthorizationController?
var paymentSummaryItems = [PKPaymentSummaryItem]()
var paymentStatus = PKPaymentAuthorizationStatus.failure
var completionHandler: PaymentCompletionHandler?

    func startPayment(client: ClientData, completion: @escaping PaymentCompletionHandler) {
        let cartTotal = client.cart.totalPrice
        let salesTax = client.cart.tax

        let amount = PKPaymentSummaryItem(label: "Amount", amount: NSDecimalNumber(value: cartTotal), type: .final)
        let tax = PKPaymentSummaryItem(label: "Tax", amount: NSDecimalNumber(value: salesTax), type: .final)
        let total = PKPaymentSummaryItem(label: "ToTal", amount: NSDecimalNumber(value: cartTotal + salesTax), type: .final)

    paymentSummaryItems = [amount, tax, total];
    completionHandler = completion

    // Create our payment request
    let paymentRequest = PKPaymentRequest()
    paymentRequest.paymentSummaryItems = paymentSummaryItems
    paymentRequest.merchantIdentifier = "merchant.com.xxxxx"
    paymentRequest.merchantCapabilities = .capability3DS
    paymentRequest.countryCode = "US"
    paymentRequest.currencyCode = "USD"
//    .phoneNumber, .emailAddress, .postalAddress
    paymentRequest.requiredShippingContactFields = []
    paymentRequest.supportedNetworks = PaymentHandler.supportedNetworks

    // Display our payment request
    paymentController = PKPaymentAuthorizationController(paymentRequest: paymentRequest)
    paymentController?.delegate = self
    paymentController?.present(completion: { (presented: Bool) in
        if presented {
            NSLog("Presented payment controller")
        } else {
            NSLog("Failed to present payment controller")
            self.completionHandler!(false)
         }
     })
  }
}

/*
    PKPaymentAuthorizationControllerDelegate conformance.
*/
extension PaymentHandler: PKPaymentAuthorizationControllerDelegate{
   
    

func paymentAuthorizationController(_ controller: PKPaymentAuthorizationController, didAuthorizePayment payment: PKPayment, completion: @escaping (PKPaymentAuthorizationStatus) -> Void) {

//    // Perform some very basic validation on the provided contact information
//    if payment.shippingContact?.emailAddress == nil || payment.shippingContact?.phoneNumber == nil {
//        paymentStatus = .failure
//    } else {
//        // Here you would send the payment token to your server or payment provider to process
//        // Once processed, return an appropriate status in the completion handler (success, failure, etc)
//        paymentStatus = .success
//    }
    let data = payment.token.paymentData
    let json = try! JSONSerialization.jsonObject(with: data, options: []) as? [String : Any]

    print(json)
    paymentStatus = .success
    completion(paymentStatus)
}

func paymentAuthorizationControllerDidFinish(_ controller: PKPaymentAuthorizationController) {
    controller.dismiss {
        DispatchQueue.main.async {
            if self.paymentStatus == .success {
                print()
                self.completionHandler!(true)
            } else {
                self.completionHandler!(false)
            }
        }
    }
}

}

我正在考虑在.success上的paymentAuthorizationControllerDidFinish()函数中发送令牌/令牌化它,并让stripe完成收费。
目前我认为步骤是:
1.当点击apple Pay时,在后端创建一个新的条带客户->将ID发送回客户端。
1.创建支付意向->将ID发送回客户端。
3...?我在这里失去了对发送条纹所有上述沿着支付来源,在我的情况下是一个加密的支付令牌由苹果。
我已经尝试发送请求到https://api.stripe.com/v1/charges?API并发送整个令牌,但它说请求无效。我知道它的野蛮强迫,但我绝望了:/

更新2

我以前

STPAPIClient.shared().createPaymentMethod(with: payment) { (source, err) in
        
        
        if let err = err {
            print(err.localizedDescription)
            self.paymentStatus = .failure
            completion(self.paymentStatus)
        }
        // returns a hashable [dictionary]
      
        guard let sourceDetails = source?.allResponseFields else
        {
            self.paymentStatus = .failure
            return
        }
        print(sourceDetails)
    

            AF.request("http://localhost:5001/rxxxxx/us-central1/paymentIntent", method: .post, parameters: ["data" : sourceDetails]).response { (response) in
                if let data = response.data {
                    guard let res = String(data: data, encoding: .utf8) else {return}
                    print(res)
                } else {
                    print("almo fire err")
                }

            }

我的后端从Stripe返回成功响应[已删除]

However, nothing has been charged or created in my Stripe dashboard.

**UPDATE 3**

I was able to confirm the payment intent using postman and calling the API and passing in the PayMent Method id directly. Still trying to implement using typescript.

LAST QUESTION. Is this PCI compliance? I have zero idea how all this is working. No client is created in dashboard, is this even working? The charges are being posted though. I am just confused because everything that i passed around didn't even show a full card number....
eqqqjvef

eqqqjvef1#

如果您没有使用Stripe iOS SDK,请尝试将PKPayment的属性传递给Stripe上的/v1/tokens端点,参数如下所示:https://github.com/stripe/stripe-ios/blob/a05b307c8a9ef6ee6c53726da2392073b5292f19/Stripe/STPAPIClient%2BApplePay.swift#L156-L189和
这将返回一个Token对象。使用Token对象(因为Token是遗留的)和/v1/payment_methods端点创建PaymentMethod对象,并传递card: {token: tok_visa },这会返回一个PaymentMethod对象:https://stripe.com/docs/api/payment_methods/create#create_payment_method-card
现在您可以将PaymentMethod附加到PaymentIntent并在服务器端确认它。

相关问题