測(cè)試卡號(hào)地址:https://developer.apple.com/apple-pay/sandbox-testing/
注意事項(xiàng):American Express測(cè)試卡必須將手機(jī)地區(qū)設(shè)為美國!
步驟:
app store connect 添加沙盒測(cè)試員,appstore地區(qū)選美國
去測(cè)試員新郵箱認(rèn)證郵件(這一步非常重要)
將手機(jī)地區(qū)設(shè)置為美國,退出現(xiàn)有賬號(hào),用認(rèn)證過的appleid登錄測(cè)試手機(jī)
-
添加測(cè)試卡,注意添加后的正確顯示為“沙盒”
IMG_2195.PNG
當(dāng)顯示為“付款卡”說明這個(gè)測(cè)試賬號(hào)廢了,需要重新申請(qǐng)沙盒賬號(hào)。
5.創(chuàng)建Merchant IDs

image.png
6.編輯Merchant IDs,為其創(chuàng)建證書Apple Pay Payment Processing Certificate

image.png
6.為app綁定Merchant IDs,可以去xcode設(shè)置添加applepay功能也可以去網(wǎng)頁appid管理設(shè)置
7.必須使用蘋果提供的PKPaymentButton組件,type和style如下

image.png
要檢測(cè)一下功能才能顯示對(duì)應(yīng)的UI
-(AP_RESULT)checkApplePayFunctionWithSupportNetworks:(NSArray *)supportNetworks{
//系統(tǒng)提供了API來判斷當(dāng)前設(shè)備是否支持Apple Pay支付的功能。
if([PKPaymentAuthorizationController canMakePayments]){
if(![PKPaymentAuthorizationController canMakePaymentsUsingNetworks:supportNetworks]){
NSLog(@"沒有綁卡");
return AP_RESULT_UNBIND_CARD;
}else{
return AP_RESULT_CAN_PAY;
}
}else{
return AP_RESULT_UNSUPPORT;
}
}
8.PKPaymentRequest創(chuàng)建
PKPaymentRequest *request = [[PKPaymentRequest alloc] init];
// 配置商家ID
request.merchantIdentifier = @"merchant.mailegouapplepay.com";
// 配置貨幣代碼, 以及國家代碼
request.countryCode = @"CN";
request.currencyCode = @"CNY";
// 配置請(qǐng)求支持的支付網(wǎng)絡(luò) 銀聯(lián)
request.supportedNetworks = @[PKPaymentNetworkChinaUnionPay];
// 配置商戶的處理方式 3DS必須支持
request.merchantCapabilities = PKMerchantCapabilityEMV|PKMerchantCapability3DS;
// 配置購買的商品列表
PKPaymentSummaryItem *orderAmout = [PKPaymentSummaryItem summaryItemWithLabel:@"訂單金額" amount:[NSDecimalNumber decimalNumberWithString:self.payModel.orderSum]];
PKPaymentSummaryItem *totalAmount = [PKPaymentSummaryItem summaryItemWithLabel:@"麥樂購" amount:[NSDecimalNumber decimalNumberWithString:self.payModel.orderSum]];
// 注意: 支付列表最后一個(gè), 代表匯總
request.paymentSummaryItems = @[orderAmout,totalAmount];
/// 以上這些配置是必須的,當(dāng)然還有一些可選的,比如物流信息、發(fā)票地址等等,像下面這樣:
// 是否顯示發(fā)票收貨地址, 顯示哪些選項(xiàng)
request.requiredBillingAddressFields = PKAddressFieldAll;
// 是否顯示快遞地址, 顯示哪些選項(xiàng)
request.requiredShippingAddressFields = PKAddressFieldAll;
// 配置快遞方式NSArray<PKShippingMethod *>
NSDecimalNumber *price2 = [NSDecimalNumber decimalNumberWithString:@"18.0"]; // 郵費(fèi)
PKShippingMethod *method = [PKShippingMethod summaryItemWithLabel:@"順豐快遞" amount:price2];
method.detail = @"24小時(shí)內(nèi)送到";
method.identifier = @"shunfeng";
NSDecimalNumber *price3 = [NSDecimalNumber decimalNumberWithString:@"0.1"];
PKShippingMethod *method2 = [PKShippingMethod summaryItemWithLabel:@"韻達(dá)快遞" amount:price3];
method2.identifier = @"yunda";
method2.detail = @"送貨上門";
request.shippingMethods = @[method, method2];
// 配置快遞的類型
request.shippingType = PKShippingTypeStorePickup;
// 添加一些附加數(shù)據(jù)
request.applicationData = [@"buyID=12345" dataUsingEncoding:NSUTF8StringEncoding];
9.PKPaymentAuthorizationController彈出
//顯示認(rèn)證視圖
PKPaymentAuthorizationController * payment = [[PKPaymentAuthorizationController alloc] initWithPaymentRequest:request];
payment.delegate = self;
[payment presentWithCompletion:^(BOOL success) {
if (success == NO) {
[self endWithResult:NO Message:@"UI未彈出,請(qǐng)檢查apple pay相關(guān)配置,如merchantId、國家代碼、貨幣代碼等" completion:nil];
}
}];
10.代理方法
// 當(dāng)授權(quán)成功之后或者取消授權(quán)之后會(huì)調(diào)用這個(gè)代理方法
- (void)paymentAuthorizationControllerDidFinish:(PKPaymentAuthorizationController *)controller{
if (self.payResultBlock && self.userCancled == YES) {
self.payResultBlock(NO, @"用戶取消支付");
self.payResultBlock = nil;
NSLog(@"用戶取消了");
}
[controller dismissWithCompletion:nil];
}
//這個(gè)代理方法指的是支付過程中會(huì)進(jìn)行調(diào)用
- (void)paymentAuthorizationController:(PKPaymentAuthorizationController *)controller
didAuthorizePayment:(PKPayment *)payment
handler:(void (^)(PKPaymentAuthorizationResult *result))completion API_AVAILABLE(macos(11.0), ios(11.0), watchos(4.0)){
// //支付所需要的token
// NSData *data = payment.token.paymentData;
// NSString *paymentDataStr = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
// //收貨人地址
// NSString *street = payment.shippingContact.postalAddress.street;
// //收貨人電話
// NSString *phone = payment.shippingContact.phoneNumber.stringValue;
// //收貨人郵編
// NSString *post = payment.shippingContact.postalAddress.postalCode;
// //收貨人姓名
// NSString *familyName = payment.shippingContact.name.familyName;
// NSString *givenName = payment.shippingContact.name.givenName;
PKPaymentToken * token = payment.token;
NSLog(@"1111獲取token---%@", token);
//獲取訂單地址
NSString * address = payment.billingContact.postalAddress.city;
NSLog(@"1111獲取到地址: %@", address);
NSLog(@"1111驗(yàn)證通過后, 需要開發(fā)者繼續(xù)完成交易");
// 在這個(gè)位置, 我們開發(fā)人員需要把token值和商品的其他信息如:地址 id 這些 , 上傳到自己公司的服務(wù)器。然后公司的服務(wù)器和銀行的商家接口進(jìn)行接口的調(diào)用,并將接口調(diào)用返回的支付結(jié)果信息返回到這里。
//根據(jù)不同的支付結(jié)果狀態(tài),讓block調(diào)用不同的交易狀態(tài);
[self serverCheckPayment:payment handler:completion];
}
11.服務(wù)器校驗(yàn)
-(void)serverCheckPayment:(PKPayment *)payment handler:(void (^)(PKPaymentAuthorizationResult *result))completion{
__block typeof(self) wkself = self;
///轉(zhuǎn)為stripe的token,傳給后臺(tái)結(jié)算
[[STPAPIClient sharedClient] createTokenWithPayment:payment completion:^(STPToken * _Nullable token, NSError * _Nullable err) {
if (err) {
[wkself endWithResult:NO Message:@"生成stripe Token失敗" completion:completion];
}else{
NSLog(@"stripeToken :%@",token);
//將token告知后臺(tái),請(qǐng)求扣款
[NetTool requestType:RequestType_Post url:K_serviceChargeurl params:@{@"stripeToken":token.tokenId} header:@{} isJsonType:YES Success:^(NSDictionary * _Nonnull response) {
if ([response[@"code"] intValue] == 200) {
[wkself endWithResult:YES Message:@"支付成功" completion:completion];
}else{
NSString *msg = response[@"message"];
[wkself endWithResult:NO Message:msg completion:completion];
}
} Fail:^(XHError * _Nonnull error) {
[wkself endWithResult:NO Message:error.errorMsg completion:completion];
}];
}
}];
}