MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

Objective-C中的Apple Pay支付功能实现

2023-05-072.0k 阅读

1. 前期准备

在Objective-C中实现Apple Pay支付功能,首先要确保开发环境的准备工作到位。

1.1 开发环境与设备要求

  • 开发环境:需要安装最新版本的Xcode,因为Apple Pay相关的SDK和功能会随着Xcode版本更新而有所改进和完善。例如,Xcode 12及以上版本对Apple Pay的支持更为全面,能提供更便捷的开发接口。
  • 设备要求:用于测试Apple Pay功能的设备必须是支持该功能的iOS设备,如iPhone 6及以上机型。并且设备需要登录有效的Apple ID,同时要在“设置” - “钱包与Apple Pay”中添加至少一张有效的支付卡。

1.2 项目配置

  • 添加Capabilities:打开Xcode项目,在项目导航器中选择项目,然后在“TARGETS”下选中你的应用目标。切换到“Capabilities”选项卡,找到“Apple Pay”并将其开关打开。这一步会自动在项目的 entitlements 文件中添加相关权限,确保应用具有使用Apple Pay的能力。

  • 配置Merchant ID:Apple Pay需要一个Merchant ID来识别你的商家身份。你需要在Apple Developer网站上创建一个Merchant ID。具体步骤如下:

    1. 登录到Apple Developer网站(https://developer.apple.com/)。
    2. 在“Certificates, Identifiers & Profiles”中,选择“Identifiers”,然后点击“+”按钮创建新的标识符。
    3. 选择“Merchant ID”,填写描述和ID。ID通常采用反向域名格式,例如“com.yourcompany.merchant”。
    4. 点击“Continue”并提交,完成Merchant ID的创建。
  • 下载并配置Merchant Certificate:创建Merchant ID后,需要下载与之关联的Merchant Certificate。

    1. 在Apple Developer网站的“Certificates, Identifiers & Profiles”中,选择“Certificates”。
    2. 点击“+”按钮,在“Payment Processing”类别下选择“Merchant ID Certificate”。
    3. 按照提示操作,使用Keychain Access生成证书签名请求文件(CSR),上传到网站完成证书创建。
    4. 下载证书并双击安装到Keychain Access中。然后在Xcode项目的“Build Settings” - “Code Signing - Identity”中选择刚刚安装的Merchant Certificate。

2. 初始化Apple Pay支付请求

在项目配置完成后,就可以在代码中初始化Apple Pay支付请求。

2.1 导入必要的框架

在使用Apple Pay相关功能之前,需要导入PassKit框架。在你的Objective-C文件中添加以下导入语句:

#import <PassKit/PassKit.h>

2.2 检查设备是否支持Apple Pay

在发起支付请求前,需要检查用户设备是否支持Apple Pay功能。可以通过以下代码实现:

if ([PKPaymentAuthorizationViewController canMakePayments]) {
    // 设备支持Apple Pay
} else {
    // 设备不支持Apple Pay,提示用户
}

还可以进一步检查设备支持的支付网络类型,例如:

NSArray<PKPaymentNetwork> *supportedNetworks = @[PKPaymentNetworkVisa, PKPaymentNetworkMasterCard, PKPaymentNetworkAmericanExpress];
if ([PKPaymentAuthorizationViewController canMakePaymentsUsingNetworks:supportedNetworks]) {
    // 设备支持指定的支付网络
} else {
    // 设备不支持指定的支付网络
}

2.3 创建支付请求

创建PKPaymentRequest对象来定义支付的详细信息,包括商家标识符、支持的支付网络、支付金额等。以下是一个示例:

PKPaymentRequest *paymentRequest = [[PKPaymentRequest alloc] init];
paymentRequest.merchantIdentifier = @"com.yourcompany.merchant";
paymentRequest.supportedNetworks = @[PKPaymentNetworkVisa, PKPaymentNetworkMasterCard, PKPaymentNetworkAmericanExpress];
paymentRequest.countryCode = @"US";
paymentRequest.currencyCode = @"USD";

PKPaymentSummaryItem *totalItem = [PKPaymentSummaryItem summaryItemWithLabel:@"Total" amount:[NSDecimalNumber decimalNumberWithString:@"10.00"]];
paymentRequest.paymentSummaryItems = @[totalItem];

在上述代码中:

  • merchantIdentifier设置为在Apple Developer网站上创建的Merchant ID。
  • supportedNetworks指定了支持的支付网络,这里包括Visa、MasterCard和American Express。
  • countryCodecurrencyCode分别设置为支付的国家代码和货币代码。
  • paymentSummaryItems定义了支付的总金额和标签。你也可以添加多个PKPaymentSummaryItem来显示详细的费用明细,例如商品价格、税费、运费等。

3. 显示支付界面

创建好支付请求后,需要显示Apple Pay的支付界面供用户进行支付操作。

3.1 创建支付授权视图控制器

使用PKPaymentAuthorizationViewController来显示支付界面。代码如下:

PKPaymentAuthorizationViewController *paymentController = [[PKPaymentAuthorizationViewController alloc] initWithPaymentRequest:paymentRequest];
if (paymentController) {
    paymentController.delegate = self;
    [self presentViewController:paymentController animated:YES completion:nil];
} else {
    // 无法创建支付控制器,可能是支付请求有问题,提示用户
}

在上述代码中:

  • 使用initWithPaymentRequest:方法初始化PKPaymentAuthorizationViewController,传入之前创建的paymentRequest对象。
  • 设置delegate为当前视图控制器(假设当前视图控制器遵循PKPaymentAuthorizationViewControllerDelegate协议),以便处理支付结果。
  • 使用presentViewController:animated:completion:方法显示支付界面。

3.2 实现支付授权视图控制器代理方法

PKPaymentAuthorizationViewControllerDelegate协议定义了处理支付结果的方法。需要实现以下两个主要方法:

- (void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller
                   didAuthorizePayment:(PKPayment *)payment
                            completion:(void (^)(PKPaymentAuthorizationStatus status))completion {
    // 处理支付授权
    // 这里可以将支付信息发送到服务器进行验证和处理
    // 验证成功后调用completion(PKPaymentAuthorizationStatusSuccess);
    // 验证失败调用completion(PKPaymentAuthorizationStatusFailure);
}

- (void)paymentAuthorizationViewControllerDidFinish:(PKPaymentAuthorizationViewController *)controller {
    // 支付界面关闭,无论支付成功与否,都可以在这里进行界面清理等操作
    [controller dismissViewControllerAnimated:YES completion:nil];
}

paymentAuthorizationViewController:didAuthorizePayment:completion:方法中:

  • payment对象包含了用户的支付信息,如支付卡信息、交易金额等。你需要将这些信息发送到你的服务器进行验证和处理。
  • 服务器验证支付信息合法后,调用completion(PKPaymentAuthorizationStatusSuccess)告知系统支付成功;如果验证失败,调用completion(PKPaymentAuthorizationStatusFailure)

paymentAuthorizationViewControllerDidFinish:方法中,关闭支付界面,通常可以在这里进行一些后续操作,如更新订单状态显示等。

4. 服务器端验证

Apple Pay支付流程中,服务器端验证是确保支付安全性和准确性的关键环节。

4.1 接收支付信息

当用户在设备上授权支付后,客户端会将支付信息发送到服务器。支付信息主要包含在PKPayment对象中,其中关键的部分是PKPaymentToken。在Objective-C中,你可以从PKPayment对象获取支付令牌并发送到服务器:

NSData *paymentToken = payment.token.paymentData;
// 将paymentToken发送到服务器

服务器接收到支付令牌后,需要对其进行解析和验证。

4.2 验证支付令牌

Apple Pay支付令牌是经过加密和签名的,服务器需要使用Apple提供的验证服务来验证令牌的合法性。验证步骤大致如下:

  1. 解析令牌:支付令牌是一个JSON Web Token(JWT)格式的数据,服务器需要解析这个JWT来获取其中的有效信息,如支付金额、支付卡信息摘要等。
  2. 验证签名:使用Apple提供的公钥来验证令牌的签名,确保令牌没有被篡改。
  3. 验证令牌有效期:检查令牌的有效期,确保支付是在令牌有效时间内发起的。

以下是一个简单的伪代码示例,展示如何在服务器端验证支付令牌(假设使用的是基于Node.js和Express框架的服务器):

const jwt = require('jsonwebtoken');
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
app.use(bodyParser.json());

// 假设这里的applePublicKey是从Apple官方获取的公钥
const applePublicKey = '...';

app.post('/verifyPayment', (req, res) => {
    const paymentToken = req.body.paymentToken;
    try {
        const decoded = jwt.verify(paymentToken, applePublicKey, { algorithms: ['ES256'] });
        // 验证令牌中的支付金额等信息是否与客户端请求一致
        // 验证通过返回成功
        res.json({ success: true });
    } catch (error) {
        // 验证失败返回错误
        res.json({ success: false, error: 'Payment token verification failed' });
    }
});

const port = 3000;
app.listen(port, () => {
    console.log(`Server running on port ${port}`);
});

在实际应用中,还需要考虑更多的安全因素,如与支付网关的集成、防止重放攻击等。

4.3 处理支付结果

服务器验证支付令牌通过后,需要根据业务逻辑处理支付结果。这可能包括更新订单状态、扣除库存、记录交易日志等操作。例如,在一个电商应用中,服务器验证支付成功后,会将订单状态从“待支付”更新为“已支付”,并通知仓库准备发货。

5. 错误处理与优化

在实现Apple Pay支付功能过程中,不可避免地会遇到各种错误情况,需要进行妥善处理,同时还可以对支付流程进行优化。

5.1 错误处理

  • 设备不支持错误:当[PKPaymentAuthorizationViewController canMakePayments]返回NO时,需要友好地提示用户设备不支持Apple Pay功能,并引导用户选择其他支付方式,例如显示一个提示框:
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"不支持Apple Pay" message:@"您的设备不支持Apple Pay支付,请选择其他支付方式。" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil];
[alertController addAction:okAction];
[self presentViewController:alertController animated:YES completion:nil];
  • 支付请求创建错误:如果在创建PKPaymentRequest对象或PKPaymentAuthorizationViewController对象时出现错误,例如传入的参数不合法,需要记录错误日志以便后续排查,并向用户显示一个通用的错误提示,如“支付请求创建失败,请稍后重试”。
  • 支付验证错误:在服务器端验证支付令牌失败时,需要向客户端返回错误信息,客户端根据错误信息提示用户支付失败原因。例如,如果是签名验证失败,可以提示“支付验证失败,请检查网络或稍后重试”。

5.2 优化支付流程

  • 预加载支付信息:在用户进入支付页面之前,可以提前加载一些支付相关的信息,如商品价格、商家信息等,减少用户在支付界面的等待时间。例如,可以在视图控制器的viewDidLoad方法中异步获取这些信息并存储起来,当创建支付请求时直接使用。
  • 优化用户界面:确保支付界面简洁明了,易于操作。例如,将支付金额、支付方式等重要信息突出显示,减少用户的误操作。同时,提供清晰的支付流程引导,让用户清楚知道每一步的操作和支付状态。
  • 缓存支付信息:对于一些经常使用Apple Pay支付的用户,可以考虑在本地缓存部分支付信息,如支付卡的后四位数字、常用的收货地址等,方便用户下次支付时快速选择,提高支付效率。但要注意缓存信息的安全性,避免敏感信息泄露。

通过以上详细的步骤和代码示例,你可以在Objective-C项目中成功实现Apple Pay支付功能,并处理好各种可能出现的情况,为用户提供安全、便捷的支付体验。同时,在实际应用中,还需要根据具体业务需求进行更多的定制和优化。