Search code examples
iosswiftapplepay

(iOS, Apple Pay) Display multiple summary items results in a bug


I display Apple Pay dialog with multiple PKPaymentSummaryItem items:

    let paymentRequest = PKPaymentRequest()
    paymentRequest.paymentSummaryItems = [
        PKPaymentSummaryItem(label: "item 1", amount: NSDecimalNumber(decimal: 10)),
        PKPaymentSummaryItem(label: "item 2", amount: NSDecimalNumber(decimal: 20)),
        PKPaymentSummaryItem(label: "item 3", amount: NSDecimalNumber(decimal: 30))
    ]
    paymentRequest.merchantIdentifier = merchantIdentifier
    paymentRequest.merchantCapabilities = .capability3DS
    paymentRequest.currencyCode = self.currencyCode
    paymentRequest.countryCode = self.countryCode
    paymentRequest.supportedNetworks = supportedNetworks
    paymentRequest.shippingType = .servicePickup
    applePayController = PKPaymentAuthorizationController(paymentRequest: paymentRequest)

And in result I see a weird picture: On the bottom sheet dialog only item 3 is present

enter image description here

If I navigate to item details there are all three items in weird order enter image description here

I haven't found any explanation of this issue in official docs, so interesting if anyone has dealt with it on practice, and how to resolve it in the best way


Solution

  • paymentSummaryItems is not used to hold the individual line items in an order. It is a summary of the payment where the items are typically things like "goods", "tax", "shipping" etc.

    The final item that you add to your payment request must be the name of the company/organisation that is receiving the payment with the total to be paid.

    Apple Pay uses the last item in the paymentSummaryItems array as the grand total for the purchase. ... The PKPaymentAuthorizationViewController class displays this item differently than the rest of the summary items. As a result, there are additional requirements placed on both its amount and its label.

    • Set the grand total amount to the sum of all the other items in the array. This amount must be greater than or equal to zero.
    • Set the grand total label to the name of your company. This label represents the person or company receiving payment.

    IE you should add another item to your payment request which is "Acme corp" or whatever the name of the company providing the goods/services is and the total:

    paymentRequest.paymentSummaryItems = [
            PKPaymentSummaryItem(label: "Goods", amount: NSDecimalNumber(decimal: 20)),
            PKPaymentSummaryItem(label: "Tax", amount: NSDecimalNumber(decimal: 2)),
            PKPaymentSummaryItem(label: "Shipping", amount: NSDecimalNumber(decimal: 10)),
            PKPaymentSummaryItem(label: "Acme Corp", amount: NSDecimalNumber(decimal: 32))
        ]
    

    This will result in the payment sheet showing "Pay Acme Corp $32"

    And the detail view will now make sense, showing goods, tax, shipping and a grand total.