Creating Payment Requests
Payment Requests
支付請求是PKPaymentRequest
類的實例。支付請求包含一系列描述用戶的支付對象(為哪些東西付款)的概要項:可用的運送方式的列表,用戶需要提供的運送信息的描述,關于商家和支付處理的信息。
Decide Whether the User Can Make Payments 判決用戶是否有能力支付
在生成一個支付請求之前,通過調用PKPaymentAuthorizationViewController
類中的canMakePaymentsUsingNetworks:
方法判斷用戶是否能夠使用支持的系統完成支付。使用canMakePayments
方法,檢查設備的硬件和父類控制是否支持Apple Pay。
如果canMakePayments
返回NO,表示設備不支持Apple Pay。因此也不顯示Apple Pay按鈕,轉到其他的支付方式。
如果canMakePayments
返回YES,但是canMakePaymentsUsingNetworks:
返回NO,表示設備支持Apple Pay,但是用戶沒有添加任何符合要求的支付系統的卡片??蛇x擇性地去顯示一個支付設置按鈕,提示用戶設置卡片。一旦用戶點擊了該按鈕,初始化設置一個新卡的進程(例如:調用openPaymentSetup
方法)。
另外,一旦用戶按下Apple Pay按鈕,必須開始支付授權進程。在展示支付請求之前不能要求用戶執行其他任何任務。例如,如果用戶需要輸入折扣碼,必須在按下Apple Pay按鈕之前請求該代碼。
Bridging from Web-Based Interfaces 基于網絡接口進行橋接
如果app使用網絡接口購買物品和服務,必須在處理Apple Pay交易之前從網絡接口移動該請求到本地iOS代碼。列表3-1展示了需要處理web view的請求的步驟。
Listing 3-1Buying items from a web view
// 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);
}
Payment Requests Include Currency and Region Information 包括貨幣和地區信息的支付請求
在支付請求中所有的概要數值均使用相同的貨幣(指定使用PKPaymentRequest
類中的currencyCode
屬性),均使用三個字母的ISO貨幣代碼,例如USD。
支付請求的國家碼表明在該國家發生購買操作或者在該國家購買將要被處理。使用兩個字母的ISO國家碼,例如US。
在支付請求中設置的商戶ID(merchant ID)必須與app中的entitlement中的merchant IDs相匹配.
request.currencyCode = @"USD";
request.countryCode = @"US";
request.merchantIdentifier = @"merchant.com.example";
Payment Requests Have a List of Payment Summary Items支付請求有一個支付概要項的列表
展示在PKPaymentSummaryItem
類中的支付概要項,描述給用戶的支付請求的不同部分。使用一個小部分的概要項- 典型地包含總和、任何折扣、運費、稅金和最終的總和。如果沒有任何其他額外的費用(例如:運費或稅金),僅僅包含購物的總和。在app中提供逐項的消費細節。
每個概要項有一個標記和數值,展示在Listing 3-2。標記是用戶可讀的概要項總結的描述。該數值與支付數值是一致的。在支付請求中的所有數值均使用在支付請求中指定的貨幣。折扣或者優惠劵的數值,則設置為負數。
當支付被授權的時候,如果不知道某個實際的費用(例如:打車費),生成一個使用PKPaymentSummaryItemTypePending
類型的總和概要項并且值為0.0。該系統然后標記該費用為未決定的。
Listing 3-2Creating a payment summary item
// 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為基的數。該類的實例可以通過明確地指定尾數和指數(展示在代碼列表中)或者提供一個string
類型的數量并指定一個區域來創建。總是使用以10為基的數來進行金融計算,例如,確定5%折扣的數量。
即使IEEE的浮點類型數據例如float
和Double
顯示起來非常方便,但不適合于金融計算。這些數據類型使用以2為基的數字表示出來,這意味著一些小數數值不能被精確地表示出來。例如:0.42很可能接近于0.419999無限循環。這類近似值會造成金融計算得到錯誤的結果。
在列表中最后的一個支付概要項是最終的總和。通過添加所有其他的概要項數值來計算總和數值。最終總和的顯示不同于其他的概要項:使用公司的名稱作為它的label
內容,使用所有其他的概要項的數值之和作為它的數值。使用paymentSummaryItems
屬性添加支付概要項到支付請求。
// 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;
A Shipping Method Is a Special Payment Summary Item 運送方式是一種特殊的支付概要項
為每個適用的運送方式創建一個PKShippingMethod
的實例。正如其他的支付概要項一樣,運送方式有一個用戶可讀label
內容(例如“標準的運送”或者“次日運送”)和一個運費的數值。不像其他的概要項,運送方式也有detail屬性-例如:“Arrives by July 29”或者“Ships in 24 hours”- 這說明了運送方式之間的不同。
為了在代理方法中區分運送方式,可使用identifier
屬性。該屬性僅僅被用于在自己的app中-框架處理它作為一個不透明的值,也不顯示在UI界面中。當創建每個運送方式時,為它指定一個獨一無二的標識。為了使調試容易些,使用摘要或者簡短的string
值,例如“discount”,“standard”或者“next-day”。
一些運送方式不適用于所有的區域或者對不同的地址有不同的運費。當用戶選擇一個運送地址或者方式時可以更新這些信息,正如Your Delegate Updates Shipping Methods and Costs中描述的。
Indicating Your Support Payment Processing Mechanisms 指定支持的支付處理機制
通過用string
常量的數組填充supportNetworks
屬性來指定支持何種支付系統。通過給merchantCapabilities
屬性設定一個值來指定支持何種支付處理協議。必須支持3DS,支持EMV是可選的。
商家支付能力是位掩碼,聯合展示如下:
request.supportedNetworks = @[PKPaymentNetworkAmex, PKPaymentNetworkDiscover, PKPaymentNetworkMasterCard, PKPaymentNetworkVisa];
// Supports 3DS only
request.merchantCapabilities = PKMerchantCapability3DS;
// Supports both 3DS and EMV
request.merchantCapabilities = PKMerchantCapability3DS | PKMerchantCapabilityEMV;
Indicating What Shipping and billing Information Is Needed 指定哪些運送和賬單信息是必需的
填充支付授權視圖控制器的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中的廣泛的輸入源。在使用它之前總是驗證這些信息。
Storing Additional Information 存儲額外的信息
為了存儲每個app特定的支付請求的信息,例如一個購物車標識,使用applicationData
屬性。該屬性被對待作為一個系統提供的不透明的值。當用戶授權支付請求之后一大把應用數據會顯示在支付密鑰中。