【问题标题】:Apple in app provisioning 'Could not add card'Apple 在应用程序配置中“无法添加卡”
【发布时间】:2021-07-01 12:28:09
【问题描述】:

我正在实施苹果应用内配置,并按照苹果指南中的所有步骤操作,但最后,我收到一条消息“无法添加卡”,但在此过程中没有任何错误。 我就是这样创建PKAddPaymentPassViewController

      let cardInfoPass  = PKAddPaymentPassRequestConfiguration.init(encryptionScheme: PKEncryptionScheme.ECC_V2);
  cardInfoPass?.cardholderName = cardholderName as? String; //The name of the person as shown on the card.
  cardInfoPass?.primaryAccountSuffix = primaryAccountSuffix as? String; //The last four or five digits of the card’s number.
  cardInfoPass?.localizedDescription = localizedDescription as? String; //A short description of the card.
  cardInfoPass?.paymentNetwork = PKPaymentNetwork.masterCard;
  
  cardInfoPass?.primaryAccountIdentifier = primaryAccountIdentifier as? String; // A primary account identifier, used to filter out pass libraries.

cardholderName是写在卡片上的名字 primaryAccountSuffix 卡上写的最后 4 位数字 localizedDescription银行名称 paymentNetwork我们用的是万事达卡 primaryAccountIdentifier 是来自 iTunes 的号码,1MNJDDA667.com.bank.package.name

我认为这部分是正确的3 个值,他们将其发送给我

...
  let certificateLeaf = certificates[0].base64EncodedString();
  let certificateSubCA = certificates[1].base64EncodedString();
  let nonceString = nonce.base64EncodedString();
  let nonceSignature = nonceSignature.base64EncodedString();
  ...
  let reqDataDic: [String: Any]  = [
    "cardId": cardId,
    "applePublicCertificate": certificateSubCA,
    "nonce": nonceString,
    "nonceSignature": nonceSignature,
    "customerId": customerId,
    "deviceId": deviceId,
  ]
  ....
  var request = URLRequest(url: url)
  request.httpMethod = "POST"
  ....
  request.httpBody = try? JSONSerialization.data(withJSONObject: reqDataDic, options: .prettyPrinted)

UPDATE2:我们现在像这样发送 nonce 和 nonceSignature 为十六进制

extension Data {
    struct HexEncodingOptions: OptionSet {
        let rawValue: Int
        static let upperCase = HexEncodingOptions(rawValue: 1 << 0)
    }

    func hexEncodedString(options: HexEncodingOptions = []) -> String {
        let format = options.contains(.upperCase) ? "%02hhX" : "%02hhx"
        return self.map { String(format: format, $0) }.joined()
    }
}
...
      let nonceData = Data(bytes: nonce)
  let nonceHex = nonceData.hexEncodedString();
  
  let nonceSignatureData = Data(bytes: nonceSignature)
  let nonceSignatureHex = nonceSignatureData.hexEncodedString();

将我需要的所有值发回给我:activationDataephemeralPublicKeyencryptedPassData 它以 JSON 对象的形式返回,因此我需要将其转换为 Data 并将所有这些值放入 handler

这就是我将数据放入处理程序的方式:

          if let dictionaryJson = try JSONSerialization.jsonObject(with: data!, options: []) as? [String: Any] {

        let activationDataString = dictionaryJson["activationData"] as! String;
        let ephemeralPublicKeyString = dictionaryJson["ephemeralPublicKey"] as! String;
        let encryptedPassDataString = dictionaryJson["encryptedPassData"] as! String;

        let activationData = activationDataString.data(using: .utf8)
        let ephemeralPublicKey  = Data(base64Encoded: ephemeralPublicKeyString)
        let encryptedPassData = Data(base64Encoded: encryptedPassDataString)
        
        let paymentPassRequest = PKAddPaymentPassRequest.init()

        paymentPassRequest.activationData = activationData;
        paymentPassRequest.encryptedPassData = encryptedPassData;
        paymentPassRequest.ephemeralPublicKey = ephemeralPublicKey;

        handler(paymentPassRequest)
     }

我将所有数据填写到paymentPassRequest 中,看起来一切正常 xCode 没有抱怨。 此时苹果钱包显示一个警告对话框,提示无法添加带有 2 个按钮的卡,稍后再试或重试....

  • 我有一张在 MasterCard 方面列入白名单的卡
  • 我在模拟器、真实设备以及 TestFlight 中的应用上尝试过

更新:

我们发现来自 Apple 的错误

回复:

https://nc-pod4-smp-device.apple.com:443/broker/v4/devices/042D1xxxxxxxxxxxxx2C52/cards 500

  {
    Connection = close;
    "Content-Length" = 81;
    "Content-Type" = "application/json";
    Date = "Thu, 08 Jul 2021 08:35:25 GMT";
    Vary = "accept-language";
    "X-Pod" = "nc-pod4";
    "X-Pod-Region" = "paymentpass.com.apple";
    "x-conversation-id" = b2axxxxxxxxxxx9e6a4d;
  }
  {
    statusCode = 500;
    statusMessage = "Broker Service Response exception";
  }

【问题讨论】:

    标签: ios swift react-native


    【解决方案1】:

    您正在使用 Hex 格式对 nonce、nonce 签名进行编码以将其发送到您的服务器,并且在收到响应后,您正尝试使用 base64 和 utf8 转换它们。尝试使用 Hex,它应该可以工作。

    我们正在使用以下转换

    - (NSData *)dataFromHexString:(NSString *)string
    {
        string = [string lowercaseString];
        NSMutableData *data= [NSMutableData new];
        unsigned char whole_byte;
        char byte_chars[3] = {'\0','\0','\0'};
        int i = 0;
        int length = string.length;
        while (i < length-1) {
            char c = [string characterAtIndex:i++];
            if (c < '0' || (c > '9' && c < 'a') || c > 'f')
                continue;
            byte_chars[0] = c;
            byte_chars[1] = [string characterAtIndex:i++];
            whole_byte = strtol(byte_chars, NULL, 16);
            [data appendBytes:&whole_byte length:1];
        }
        return data;
    }
    
    -(NSMutableString *) convertToString:(NSData *)data{
      NSUInteger capacity = data.length * 2;
      NSMutableString *sbuf = [NSMutableString stringWithCapacity:capacity];
      const unsigned char *buf = data.bytes;
      NSInteger i;
      for (i=0; i<data.length; ++i) {
        [sbuf appendFormat:@"%02x", (NSUInteger)buf[i]];
      }
      return  sbuf;
    }
    

    【讨论】:

      【解决方案2】:

      let activationData = activationDataString.data(using: .utf8)

      我认为这种编码仅适用于 VISA。

      对于万事达卡,它必须是 base64:

      let activationData = Data(base64Encoded: activationDataString)

      【讨论】:

        猜你喜欢
        • 2021-03-09
        • 1970-01-01
        • 2017-04-15
        • 1970-01-01
        • 2016-12-02
        • 1970-01-01
        • 2015-05-05
        • 1970-01-01
        • 2019-10-05
        相关资源
        最近更新 更多