苹果支付账单地址税计算

Posted

技术标签:

【中文标题】苹果支付账单地址税计算【英文标题】:Apple pay billing address tax calculation 【发布时间】:2021-10-24 17:48:17 【问题描述】:

我正在尝试通过以下流程使用 Stripe 实施 Apple pay

选择产品 点击apple pay(显示的商品摘要不含税) 在选择/更新帐单地址后,将计算税金并更新 paymentSummaryItems 以显示最终金额 付款

但我找不到在付款授权之前提取帐单信息以计算和应用税款的方法。对于送货地址,有一个委托回调

func applePayContext(_ context: STPApplePayContext, didSelectShippingContact contact: PKContact, handler: @escaping (PKPaymentRequestShippingContactUpdate) -> Void) 

每次更新送货地址时都会调用它,但账单地址不一样。

这是正确的流程还是应该在显示PKPaymentAuthorizationController之前计算税金?

【问题讨论】:

【参考方案1】:

结果证明帐单地址有回调,但它在PKPaymentAuthorizationControllerDelegate

    // update the summary items in response to the card type changing (for example, applying credit card surcharges)
    //
    // The delegate will receive no further callbacks except paymentAuthorizationControllerDidFinish:
    // until it has invoked the completion block.
    
    @available(ios 11.0, *)
    optional func paymentAuthorizationController(_ controller: PKPaymentAuthorizationController, didSelectPaymentMethod paymentMethod: PKPaymentMethod, handler completion: @escaping (PKPaymentRequestPaymentMethodUpdate) -> Void)

问题是 Stripe 的 STPApplePayContext 没有实现它,因此没有将它传递给它自己的代表 STPApplePayContextDelegate,就像它对送货地址所做的那样。

快速的解决方案是自己实现:

struct AssociatedKeys 
    static var postalCodeCompletion: String = "postalCodeCompletionKey"


extension STPApplePayContext 
    // 1
    var didUpdatePostalCodeCompletion: ((CNPostalAddress, (PKPaymentRequestPaymentMethodUpdate) -> Void) -> ())? 
        get 
            guard let value = objc_getAssociatedObject(self, &AssociatedKeys.postalCodeCompletion) as? (CNPostalAddress, (PKPaymentRequestPaymentMethodUpdate) -> Void) -> () else 
                return nil
            
            return value
        
        set(newValue) 
            objc_setAssociatedObject(self, &AssociatedKeys.postalCodeCompletion, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        
    
    
    @objc
    public func paymentAuthorizationController(_ controller: PKPaymentAuthorizationController,
                                               didSelectPaymentMethod paymentMethod: PKPaymentMethod,
                                               handler completion: @escaping (PKPaymentRequestPaymentMethodUpdate) -> Void) 
        // 2
        guard let address = paymentMethod.billingAddress?.postalAddresses.first?.value else 
            let error = PKPaymentError(.billingContactInvalidError)
            let paymenMethodUpdate = PKPaymentRequestPaymentMethodUpdate(errors: [error], paymentSummaryItems: [])
            completion(paymenMethodUpdate)
            
            return
        
        
        didUpdatePostalCodeCompletion?(address, completion)
    

    由于我们使用扩展,关联对象是存储值的方式 我只需要这里的地址(是的,它不完整)所以我只将它传递给存储的完成 + 来自委托的完成

注意:您必须在准备好计算后立即从委托中调用完成

使用方法:

        let merchantIdentifier = "your merch ID"
        let paymentRequest = StripeAPI.paymentRequest(withMerchantIdentifier: merchantIdentifier, country: "US", currency: "USD")

        // 1
        paymentRequest.paymentSummaryItems = []

        // Initialize an STPApplePayContext instance
        if let applePayContext = STPApplePayContext(paymentRequest: paymentRequest, delegate: self) 
            // Present Apple Pay payment sheet
            
            applePayContext.didUpdatePostalCodeCompletion =  address, completion in
                
                // 2
                let newSummaryItems = [
                    PKPaymentSummaryItem(label: "my new fancy hat", amount: 1),
                    PKPaymentSummaryItem(label: "Tax", amount: 1),
                    PKPaymentSummaryItem(label: "Total", amount: 2)
                ]
                
                let pkpaymentrequest = PKPaymentRequestPaymentMethodUpdate(errors: nil, paymentSummaryItems: newSummaryItems)
                // 3
                completion(pkpaymentrequest)
            
            applePayContext.presentApplePay(completion: nil)

         else 
            print("There is a problem with your Apple Pay configuration")
        
    
    生成初始汇总项 根据地址进行任何计算以获取税款或任何额外费用 您必须调用从 PKPaymentAuthorizationControllerDelegate 传递的完成(尚未测试,但基于 didAuthorizePayment,您有大约 30 秒的时间来完成)

【讨论】:

嗨,@wootage 感谢您的回答。但是 applePayContext.didUpdatePostalCodeCompletion 没有执行。 哦,它只进入“paymentSummeryitem”,而不是 requiredShippingContactFields。是否可以在 requiredShippingContactFields 上添加这个? didSelectShippingContact 在条带框架中实现,并有自己的委托STPApplePayContextDelegate.applePayContext(_:didSelectShippingContact:handler:))。您可以在课堂上实现它并处理运输部分【参考方案2】:

在没有送货地址的情况下使用 Apple Pay 时,您应在显示 Apple Pay 表之前收集计算税款所需的信息,并在要求您的客户付款时包括税款信息(这意味着税款应作为一个单独的项目显示Apple Pay 表上)。

如果您要收集送货地址,您将使用STPApplePayContextDelegate 根据送货地址计算税费,以便在客户选择/更改送货地址时更新 Apple Pay 表上显示的税费。

出于隐私原因,Apple Pay 不会在客户确认付款之前向您提供账单地址,并且在确认付款之前仅提供部分送货地址:

为了保护隐私,发货信息是匿名的。例如,在美国,它只包括城市、州和邮政编码。这提供了足够的信息来计算运费,而在用户实际批准购买之前不会泄露敏感信息。

【讨论】:

以上是关于苹果支付账单地址税计算的主要内容,如果未能解决你的问题,请参考以下文章

苹果税遭重击!法院判决:App Store必须90天内开放第三方支付,苹果市值一夜蒸发5477亿...

苹果税要崩溃了!又一国家做出判决:iOS必须开放第三方支付

赚钱鬼才:即使开放外部支付,苹果App Store仍坚持收取佣金

苹果税是时候改了,它将失去一大笔利润,还能继续高傲么?

苹果“屈服”了?App Store 竟允许第三方支付!

堡垒之夜诉苹果案后,应用程序开发商正开发新软件规避“苹果税”