如何將PKPaymentPass新增到PKPassLibrary (即在客戶端裡執行新增卡片操作,填完之後會在wallet顯示)
關鍵詞
com.apple.developer.payment-pass-provisioning
PKAddPaymentPassRequestConfiguration
PKAddPaymentPassViewController
PKAddPaymentPassRequest
PKPassLibrary
PKAddPassButton
PKPaymentPass
下面是開發的步驟及遇到的問題
1.向蘋果公司的人員申請Wallet(官方說是passKit)許可權
2.許可權配好後,在開發者中心配置一下Application Services:
3.編輯描述檔案選擇下圖所示,並重新生成,沒有其他的什麼檔案
4.xcode工程配置 開啟wallet
5.然後配置一下工程中的檔案 填入com.apple.developer.payment-pass-provisioning欄位,確定這個entitlements檔案已加到工程裡
6.申請沙盒賬號:就是假的icloud賬號,可以用第7步的賬號直接在wallet試試
7.官方網站提供的測試賬號可以直接在wallet應用里加上
8.申請測試卡賓:即測試賬號的前6位
9.開發中遇到報錯:蘋果查需要提供SEID,銀聯查需要提供卡號
10:有效期的格式需要傳斜槓
10.報錯"無法新增卡"有很多原因
如果把密文給蘋果直接報錯“無法新增卡”,那就是加密錯誤,祕鑰是一個數組需要都傳給後臺。
11.報錯“卡片有誤”,說明加解密已過,是我們自己這邊的卡可能被鎖
12.開發此功能的設定支援的iOS版本可以低於10.3,如果使用tesfflight測試此功能需要提高到10.3.
13.上程式碼
//設定加密型別 PKAddPaymentPassRequestConfiguration *con = [[PKAddPaymentPassRequestConfiguration alloc]initWithEncryptionScheme:PKEncryptionSchemeRSA_V2]; con.cardholderName = @"介面展示用"; con.localizedDescription = @"加卡";//描述資訊 if (IOS10_OR_LATER) { con.paymentNetwork = PKPaymentNetworkChinaUnionPay;//銀聯卡 } con.primaryAccountSuffix = @“1111”;卡號結尾4位 PKAddPaymentPassViewController *vc = [[PKAddPaymentPassViewController alloc] initWithRequestConfiguration:con delegate:self]; [XXX.rootViewController pushViewController:vc animated:YES]; 然後實現下面的方法 - (void)addPaymentPassViewController:(PKAddPaymentPassViewController *)controller generateRequestWithCertificateChain:(NSArray<NSData *> *)certificates nonce:(NSData *)nonce nonceSignature:(NSData *)nonceSignature completionHandler:(void(^)(PKAddPaymentPassRequest *request))handler;{ NSString *leafBase64Encoded = [certificates[0] base64EncodedStringWithOptions:0]; NSString *subBase64Encoded = [certificates[1] base64EncodedStringWithOptions:0]; NSArray * cerArray = @[leafBase64Encoded,subBase64Encoded]; NSString *nonceStr = [self convertDataToHexStr:nonce]; NSString *nonceSignatureStr = [self convertDataToHexStr:nonceSignature]; //然後往後臺發介面 注意cerArray直接發給後臺 //後臺返回密碼等資料 然後回傳給sdk NSString *encryptedPassString = params[@"encryptedPassData"]; encryptedPassString = [encryptedPassString stringByReplacingOccurrencesOfString:@" " withString:@""]; encryptedPassString = [encryptedPassString stringByReplacingOccurrencesOfString:@"\r\n" withString:@""]; encryptedPassString = [encryptedPassString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; NSData *encryptedPassData=[[NSData alloc] initWithBase64EncodedString:encryptedPassString options:0]; NSString *activationString = params[@"activationData"]; activationString = [NSString stringWithFormat:@"%@|%@",nonceSignatureStr, params[@"activationData"]]; NSData *activationData = [activationString dataUsingEncoding:NSUTF8StringEncoding]; NSString *wrappedKeyString = params[@"wrappedKey"]; wrappedKeyString = [wrappedKeyString stringByReplacingOccurrencesOfString:@" " withString:@""]; wrappedKeyString = [wrappedKeyString stringByReplacingOccurrencesOfString:@"\r\n" withString:@""]; wrappedKeyString = [wrappedKeyString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; NSData *wrappedKey=[[NSData alloc] initWithBase64EncodedString:wrappedKeyString options:0]; wrappedKey = [EncodeAndDecode dataFromHexString:wrappedKeyString]; encryptedPassData = [EncodeAndDecode dataFromHexString:encryptedPassString]; PKAddPaymentPassRequest *request = [[PKAddPaymentPassRequest alloc] init]; request.activationData = activationData; request.encryptedPassData = encryptedPassData; request.wrappedKey = wrappedKey; if (request == nil) { return; } if (handler) { handler(request); } //下面這個方法 失敗會走但沒什麼有用的資訊 - (void)addPaymentPassViewController:(PKAddPaymentPassViewController *)controller didFinishAddingPaymentPass:(nullable PKPaymentPass *)pass error:(nullable NSError *)error;{ } //進位制轉換 - (NSString *)convertDataToHexStr:(NSData *)data { if (!data || [data length] == 0) { return @""; } NSMutableString *string = [[NSMutableString alloc] initWithCapacity:[data length]]; [data enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop) { unsigned char *dataBytes = (unsigned char*)bytes; for (NSInteger i = 0; i < byteRange.length; i++) { NSString *hexStr = [NSString stringWithFormat:@"%x", (dataBytes[i]) & 0xff]; if ([hexStr length] == 2) { [string appendString:hexStr]; } else { [string appendFormat:@"0%@", hexStr]; } } }]; return string; }
注意:1.證書要編碼傳給後臺,對證書編碼這裡用base64和平時用的沒有區別
2.nonce要轉成16進位制傳給後臺 不是做base64。使用convertDataToHexStr方法或下面這個都行
NSString *nOnce = [NSString stringWithFormat:@"%@",nonce];
nOnce = [nOnce stringByReplacingOccurrencesOfString:@"<" withString:@""];
nOnce = [nOnce stringByReplacingOccurrencesOfString:@">" withString:@""];
nOnce = [nOnce stringByReplacingOccurrencesOfString:@" " withString:@""];
3.nonceSignature同上
4.後臺返回的資料如何給蘋果,encryptedPassData和wrappedKey需要直接從16進位制字串轉為nsdata
方法是
+ (NSData *) dataFromHexString:(NSString*)hexString
{
NSString * cleanString = [SM4EncodeAndDecode cleanNonHexCharsFromHexString:hexString];
if (cleanString == nil) {
return nil;
}
NSMutableData *result = [[NSMutableData alloc] init];
int i = 0;
for (i = 0; i+2 <= cleanString.length; i+=2) {
NSRange range = NSMakeRange(i, 2);
NSString* hexStr = [cleanString substringWithRange:range];
NSScanner* scanner = [NSScanner scannerWithString:hexStr];
unsigned int intValue;
[scanner scanHexInt:&intValue];
unsigned char uc = (unsigned char) intValue;
[result appendBytes:&uc length:1];
}
NSData * data = [NSData dataWithData:result];
// [result autorelease];//add先去掉 可能有閃退
return data;
}
5.返回的activationData 轉成data就可以 和後臺約定一下就行
6.然後可能報錯 錯誤1
上圖的警告框下邊就一個按鈕“好”,這種情況應該是返給蘋果的資料型別不對
7.錯誤2 這個下邊兩個按鈕 如果在協議之前彈出來應該是加解密錯誤(後臺要用test vector驗仔細證) 或銀聯問題
如果在協議之後彈出來應該是自己後臺驗證的問題
在wallet裡新增或在客戶端裡新增應該走的鏈路沒啥區別都報相同的錯
8.錯誤3 如果在協議之前彈出來應該是已經過了加解密,而且這個是信用卡報出來的機率大,可以驗證第7步是否加解密沒有問題
9.如果下面的錯 加解密沒問題 卡賓沒有加到測試蘋果資料裡
10.如果銀聯沒有問題會彈出協議
11.然後加掛成功
12.注意的問題
(1)- (NSArray<PKPass *> *)passesOfType:(PKPassType)passType
這個方法如果獲取不到資料需要後臺配置一下引數:teamid.bundleid
後臺程式碼類似
"cardMetaData":{"associatedApplicationIdentifiers":[":["P2V7337495.com.elem.e","P","","P2V7337495.com.nihaom.hao"],""],"associatedStoreIdentifiers":["473489211"]
(2)名詞 fpan不太懂應該用不到
en_otp:加密驗證碼 應該指的是activationData
(3)- canAddPaymentPassWithPrimaryAccountIdentifier: 傳入的引數應該是fpan後臺給的
相關推薦
如何將PKPaymentPass新增到PKPassLibrary (即在客戶端裡執行新增卡片操作,填完之後會在wallet顯示)
關鍵詞 com.apple.developer.payment-pass-provisioning PKAddPaymentPassRequestConfiguration PKAddPaymentPassViewController PKAddPaymentPass
socket間通訊_TCP(用客戶端給執行服務端命令)
服務端: import os import socket HOST = '172.25.254.41' PORT = 9881 # 1. 建立服務端的socket物件 with socket.socket() as serverSocket:
angular2^ typescript 將 文件和Json數據 合並發送到服務器(1.客戶端處理)
src ica div .html web ready 進行 form med 首先介紹下框架基本流程 (web > webservice 【前端架構】 ) > (nodejs 【 數據中轉站 】) >(api 【後臺接口】) --web (htm
Cas 服務器 Service(Cas客戶端)註冊信息維護
操作 電腦 添加 img keytool eid div tro down 作為Cas服務器,允許哪些客戶端接入與否是通過配置來定義的。對Cas服務器來說,每一個接入的客戶端與一個Service配置對應;在Cas服務器啟動時加載並註冊上這些Service,與之對應的客戶端才
PHP規範PSR18(HTTP客戶端)介紹
本文件描述了用於傳送HTTP請求和接收HTTP響應的通用介面。 本文件中的關鍵詞“必須”,“必須”,“必需”,“應該”,“不應該”,“應該”,“不應該”,“推薦”,“可以”和“可選”按照RFC 2119中的描述進行解釋。 1 目標 此PSR的目標是允許開發人員建立與HTTP客戶端實現分離的庫
動作手遊實時PVP幀同步方案(圖解客戶端)
1、概述 1.1、基於UDP的幀同步方案 在技術選型方面,之所以選擇幀同步方案,在Kevin的一篇介紹PVP幀同步後臺實現的文章中已經做了詳細敘述,這裡簡單摘要如下: 高一致性。如果每一幀的輸入都同步了,在同樣的上下文中,計算得出的結果應該也是同步的。 低流量消耗。除了幀
重灌系統後,重新安裝ORACLE加環境變數配置、客戶端PL/SQL的安裝過程,及注意事項(避免再次踩坑)
(1)首先了解什麼是OERACLE及Oracle與PL/SQL是什麼關係: ORACLE是資料庫,有客戶端和伺服器; PLSQL Developer只是第三方工具,服務於ORACLE,類似的工具還有Toad,sqlplus,sql developer等等; 安裝PLSQL Developer
skill——zbbix(主動客戶端自動註冊)
主動客戶端自動註冊 自動註冊(agent auto-registration)功能主要用於 Agent 主動且自動向 Server 註冊。與前面的自動發現(Network discovery)具有同樣的功能 但是這個功能更適用於特定的環境:當存在一個條件未知(如 agent 端的 IP 地址段、age
(QT) C++ 版本IM通訊軟體(客戶端+伺服器文字聊天、檔案斷點續傳、線上使用者搜尋)
緊接著上一節課程,這次的作業是要求實現一個簡易版的“QQ”,可支援“軟體需求”所列出的功能。當時由於圖方便便選擇了QTCPSocket進行整個過程的通訊(事後才知道有多坑)。服務端介面比較簡單,就幾個按鈕一個進度條,主要在客戶端實現了基本的功能和介面。整個學習和
BootStrap 表格分頁(伺服器客戶端)
伺服器分頁表格 function InitMainTable1 () { //記錄頁面bootstrap-table全域性變數$table,方便應用 var queryUrl = "/XServer/user.do?_
推薦一款好用的國外網盤 mega(附客戶端下載及使用教程)
國內,免費好用的網盤基本絕跡了。比如百度網盤,免費各種限速,速度坑的一比,雖然有一些方法可以突破百度網盤限速,不過百度網盤演算法也一直在更新,可能之前有用的方法後面就失效了。而 115 網盤,也是需要付費才能體驗比較好的服務,而且費用還不便宜。 現在介紹國外的一款網盤,名為 mega 網
Java-TCP程式編寫(TCP客戶端和服務端)
1.TCP服務端的程式編寫 package test; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Sock
python網路程式設計(TCP客戶端/伺服器端實現)
下面的程式實現的功能:客戶端發來訊息,伺服器端加上時間戳返回給使用者 伺服器端: from socket import * from time import ctime import os p
Oracle Instant Client(即時客戶端) 安裝與配置
一、下載 下載地址:http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html 這是Oracle Instant Client的下載首頁,有很多種版本可供下載。 但
Windows C語言 Socket程式設計 server端(伺服器)--初級(多客戶端——初級版)
看過我的簡單版的伺服器程式碼的,會發現那段程式碼同一時間只能和一個客戶端通訊。這樣的程式碼能力很小侷限性很大。今天我來介紹一種多客戶端的伺服器程式碼。當然這段程式碼還是有問題的,至於是什麼問題我會在程式碼後面說清楚。 我的這個多客戶端的程式碼核心思想是多執行緒
Live555學習之(四)------建立RTSP連線的過程(RTSP客戶端)
Live555不僅實現了RTSP伺服器端,還實現了RTSP客戶端,我們通過testRTSPClient.cpp這個程式來看一下,Live555的RTSP客戶端與伺服器端建立RTSP連線的過程。 首先來看一下main函式: 1 char eventLoopWatchVariable =
Android-通過網路獲取xml檔案使用pull解析得到伺服器中的資訊(新聞客戶端)
通過網路獲取xml檔案,使用pull解析該檔案得到伺服器中的資訊; demo中使用了一個開源的圖片載入包,故上傳原始碼方便檢視; 效果圖: 步驟: 1.連線伺服器獲取xml檔案; 2.使用pull解析xml檔案存入實體物件中; 3.解析後將實體物件存入List集合中;
簡明Github使用教程(桌面客戶端與網頁版)
一:下載github二:安裝GitHub下載之後點選進行安裝過程,安裝之後桌面上會有兩個圖示,如下圖 三:新建專案GitHub是圖形介面模式,Git Shell是命令列模式,在Windows系統下我們使用GitHub進行程式碼管理。1:開啟GitHub圖形介面,輸入使用者名稱
DP軟體中新增一臺Windows客戶端
1.遠端新增客戶端 2. 本地安裝 本地安裝完成後再匯入 DP cell manager安裝在Linux伺服器上,打算用DP備份Windows Server 2012上檔案。就需要把Windows Server新增到DP中,用遠端安裝最方便。只
MQTT Client library for C (MQTT客戶端C語言庫-paho)
最近在使用Paho的MQTT客戶端,由於英語看著有點慢,因此將其翻譯為中文,與大家共享。由於英語水平有限,如有翻譯不對之處,請幫忙指出。 MQTT客戶端C語言庫 MQTT客戶端的C語言庫.© Copyright IBM Corp