Apple Pay編程指南(3) - 創建支付請求

Apple Pay 系列文章是蘋果官方文檔的中文翻譯,這將是最詳盡最規範的說明。
原文鏈接:
蘋果開發文檔

Apple Pay編程指南(1) - 簡介
Apple Pay編程指南(2) - 環境配置
Apple Pay編程指南(3) - 創建支付請求
Apple Pay編程指南(4) - 支付授權
Apple Pay編程指南(5) - 處理付款結果
Apple Pay編程指南(6) -沙盒測試

支付請求是PKPaymentRequest類的實例。付款請求由摘要列表組成,這些摘要向用戶描述支付的內容、可用的送貨方法列表、用戶需要提供的送貨信息的描述以及有關商家和付款處理程序的信息。

判斷是否可以支付

在創建支付請求之前,通過調用PKPaymentAuthorizationViewController類的canMakePaymentsUsingNetworks:方法,確定用戶是否能夠使用您支持的網絡進行支付。要檢查Apple Pay是否受到該設備硬件和家長控制的支持,可以使用canMakePayments方法。

注意:PKPaymentAuthorizationController類執行與PKPaymentAuthorizationViewController類相同的角色,但它不依賴於UIKit框架。這意味着授權控制器可以用於視圖控制器不能使用的地方(例如,在watchOS應用程序或intent擴展中)。

如果canMakePayments返回NO,則該設備不支持Apple Pay。不要顯示Apple Pay按鈕。回到另一種支付方式。

如果canMakePayments返回YES,而canMakePaymentsUsingNetworks:返回NO,說明設備支持Apple Pay,但是用戶沒有爲任何請求的網絡添加卡。您可以選擇顯示一個支付設置按鈕,提示用戶設置他的卡。只要用戶點擊此按鈕,就開始設置新卡的過程(例如,通過調用openPaymentSetup方法,會跳轉到wallet)。

只要用戶按下Apple Pay按鈕,就必須開始支付授權過程。在提交付款請求之前,不能要求用戶執行任何其他任務。例如,如果用戶需要輸入折扣代碼,您必須在他按下Apple Pay按鈕之前輸入。(意思是隻要按下Apple Pay按鈕,就只能執行付款流程,其他需要用戶操作的事情放在之前去做)

網頁接口橋接

如果您的應用程序使用基於web的界面來購買商品和服務,那麼在處理Apple Pay事務之前,您必須將請求從web界面移動到本機iOS代碼。以下是處理web視圖請求所需的步驟。

// Called when the web view tries to load "myShoppingApp:buyItem"
-(void)webView:(nonnull WKWebView *)webView
decidePolicyForNavigationAction:(nonnull WKNavigationAction *)navigationAction
decisionHandler:(nonnull void (^)(WKNavigationActionPolicy))decisionHandler {
 
    // Get the URL for the selected link.
    NSURL *URL = navigationAction.request.URL;
 
    // If the scheme and resource specifier match those defined by your app,
    // handle the payment in native iOS code.
    if ([URL.scheme isEqualToString:@"myShoppingApp"] &&
        [URL.resourceSpecifier isEqualToString:@"buyItem"]) {
 
        // Create and present the payment request here.
 
        // The web view ignores the link.
        decisionHandler(WKNavigationActionPolicyCancel);
    }
 
    // Otherwise the web view loads the link.
    decisionHandler(WKNavigationActionPolicyAllow);
}

支付請求包含的地區和貨幣信息

request.currencyCode = @"USD"; //人民幣是CNY
request.countryCode = @"US"; //中國是CN
request.merchantIdentifier = @"merchant.com.example"; //這是之前你設置好的Merchant ID

支付請求包含的支付清單

由PKPaymentSummaryItem類表示的付款摘要項向用戶描述付款請求的不同部分。使用少量的彙總項目——通常是小計、折扣、運費、稅金和總金額。如果您沒有任何額外的費用(例如,運費或稅),只需使用購買的總額。在應用程序的其他地方提供逐項成本的詳細信息。

每個摘要項都有一個標籤和一個金額,如清單3-2所示。標籤是用戶可讀的項目摘要描述。金額爲相應的支付金額。付款請求中的所有金額都使用付款請求中指定的貨幣。對於折扣或優惠券,將金額設置爲負數。

清單3-2:創建支付清單

// 12.75 subtotal
NSDecimalNumber *subtotalAmount = [NSDecimalNumber decimalNumberWithMantissa:1275 exponent:-2 isNegative:NO];
self.subtotal = [PKPaymentSummaryItem summaryItemWithLabel:@"Subtotal" amount:subtotalAmount];
 
// 2.00 discount
NSDecimalNumber *discountAmount = [NSDecimalNumber decimalNumberWithMantissa:200 exponent:-2 isNegative:YES];
self.discount = [PKPaymentSummaryItem summaryItemWithLabel:@"Discount" amount:discountAmount];

注意:付款彙總項使用NSDecimalNumber類將金額存儲爲基數爲10的數量。這個類的實例可以通過顯式地指定尾數和指數(如代碼清單所示)來創建,也可以通過提供數量作爲字符串並指定區域設置來創建。例如,在財務計算中一定要使用基數爲10的數字,以確定5%的折扣金額。
雖然看起來更方便,但是IEEE浮點數據類型(float和Double)不適合進行財務計算。這些數據類型使用以2爲基礎的數字表示,這意味着一些十進制數字不能被精確地表示—例如,0.42必須近似爲0.41999循環。這種近似可能導致財務計算返回不正確的結果。

(NSDecimalNumber一般用於和錢打交道的數據存儲,因爲普通的浮點是有誤差的,NSDecimalNumber彌補了這個問題)

列表中的最後一個付款彙總項是總金額。通過添加所有其他彙總項的金額來計算總金額。總計與其他彙總項的顯示方式不同:使用您的公司名稱作爲其標籤,並使用所有其他彙總項的總額作爲其金額。使用paymentSummaryItems屬性將付款摘要項添加到付款請求中。

如果您不知道授權支付時的實際成本(例如出租車費用),則使用PKPaymentSummaryItemTypePending類型和0.0金額創建一個小計彙總項目。對於總金額,使用正的非零金額和PKPaymentSummaryItemTypePending類型。然後,系統將成本顯示爲pending,沒有數字數量。

注意:總金額不能是0或者負數。

// 10.75 grand total
NSDecimalNumber *totalAmount = [NSDecimalNumber zero];
totalAmount = [totalAmount decimalNumberByAdding:subtotalAmount];
totalAmount = [totalAmount decimalNumberByAdding:discountAmount];
self.total = [PKPaymentSummaryItem summaryItemWithLabel:@"My Company Name" amount:totalAmount];
 
self.summaryItems = @[self.subtotal, self.discount, self.total];
request.paymentSummaryItems = self.summaryItems;

Shipping Method

爲每個可用的傳送方法創建PKShippingMethod的實例。與其他付款彙總項一樣,shipping方法具有用戶可讀的標籤,比如Standard shipping或Next Day shipping,以及表示運費的金額。與其他摘要項不同的是,運輸方法還有一個詳細的屬性,比如“7月29日前到達”或“24小時內到達”,這就解釋了運輸方法之間的區別。

要區分委託方法中的傳遞方法,請使用標識符屬性。此屬性僅供您的應用程序使用—框架將其視爲不透明值,並且它不會出現在UI中。在創建每個傳送方法時,爲其分配唯一標識符。爲了便於調試,可以使用簡短或縮寫的字符串,如“discount”、“standard”或“next-day”。

有些運輸方法不是在所有地區都可用,或者對於不同的地址有不同的成本。當用戶選擇送貨地址或方法時,可以更新此信息,如委託更新送貨方法和費用中所述。

支付處理機制的支持設置

通過使用字符串常量數組填充supportedNetworks屬性來指示您支持哪些支付網絡。通過爲merchantCapabilities性屬性設置一個值來指示您支持哪些支付處理協議。你必須支持3DS;只有在支持Apple Pay的情況下才能指定EMV。

request.supportedNetworks = @[PKPaymentNetworkAmex, PKPaymentNetworkDiscover, PKPaymentNetworkMasterCard, PKPaymentNetworkVisa];
 
// Supports 3DS only
request.merchantCapabilities = PKMerchantCapability3DS;
 
// Supports both 3DS and EMV (add EMV only if you support Apple Pay in China)
request.merchantCapabilities = PKMerchantCapability3DS | PKMerchantCapabilityEMV;

運輸和計費信息設置

填充付款授權視圖控制器的requiredBillingAddressFields和requiredShippingAddressFields屬性,以指示需要哪些賬單和發貨信息。當您呈現這個視圖控制器時,它會提示用戶提供所請求的帳單和發貨信息。

request.requiredBillingAddressFields = PKAddressFieldEmail;
request.requiredBillingAddressFields = PKAddressFieldEmail | PKAddressFieldPostalAddress;

注意:只要求填寫所需要的信息。請求不必要的信息會給事務增加不必要的複雜性。每一個額外的步驟都增加了用戶取消支付的可能性。

如果您有最新的賬單和發貨聯繫方式,您可以在付款請求中設置這些信息。Apple Pay默認使用這些信息;但是,用戶仍然可以選擇其他聯繫方式作爲支付授權過程的一部分。

PKContact *contact = [[PKContact alloc] init];
 
NSPersonNameComponents *name = [[NSPersonNameComponents alloc] init];
name.givenName = @"John";
name.familyName = @"Appleseed";
 
contact.name = name;
 
CNMutablePostalAddress *address = [[CNMutablePostalAddress alloc] init];
address.street = @"1234 Laurel Street";
address.city = @"Atlanta";
address.state = @"GA";
address.postalCode = @"30303";
 
contact.postalAddress = address;
 
request.shippingContact = contact;

注意:地址信息可以來自iOS中的各種來源。在使用信息之前一定要驗證它。

付一段代碼

- (void)configPaymentInformation {
    //開始配置支付信息
    self.payRequest = [[PKPaymentRequest alloc] init];
    self.payRequest.countryCode = @"US";             //國家代碼
    self.payRequest.currencyCode = @"USD";           //RMB的幣種代碼
    self.payRequest.merchantIdentifier = @"merchant.com.aspiraconnect.demo";//申請的merchantID
    
    self.payRequest.supportedNetworks = self.supportedNetworkCards; //用戶可以進行支付的銀行卡
    
    self.payRequest.merchantCapabilities = PKMerchantCapability3DS | PKMerchantCapabilityEMV;
    //設置支持的交易處理協議, 3DS必須支持, EMV爲可選
    
    //payRequest.requiredShippingAddressFields = \
    PKAddressFieldPostalAddress | PKAddressFieldPhone | PKAddressFieldName;
    //設置發貨地址
    self.payRequest.requiredShippingAddressFields = PKAddressFieldNone;
    //空發貨地址
    self.payRequest.shippingMethods = @[];
    NSDecimalNumber *totalAmount = \
    [NSDecimalNumber decimalNumberWithString:@"0.01"];//創建金額
    
    PKPaymentSummaryItem *total = \
    [PKPaymentSummaryItem summaryItemWithLabel:@"My Company Name" amount:totalAmount];
    self.summaryItems = [NSMutableArray arrayWithArray:@[total]];
    self.payRequest.paymentSummaryItems = self.summaryItems;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章