苹果支付的自动续费功能主要依托App Store的订阅机制实现,开发者需要在后端通过校验用户上传的支付收据,判断订阅的有效状态,同时处理自动续费后的状态更新逻辑。整个流程需要严格遵循苹果的官方校验规范,才能确保订阅状态判断的准确性。

苹果支付自动续费核心流程
实现苹果支付自动续费的核心逻辑可以分为以下几个步骤:
- 客户端完成订阅支付后,将支付收据上传到开发者后端
- 后端将收据发送到苹果官方校验接口进行验证
- 解析苹果返回的校验结果,判断订阅的有效状态
- 根据订阅的过期时间、自动续费状态等信息,更新用户在本地的订阅权益
- 定期轮询校验即将过期的订阅,处理自动续费后的状态同步
收据校验接口说明
苹果提供了两个收据校验接口,分别是生产环境和沙盒环境,开发者需要根据实际情况选择对应的接口地址:
| 环境类型 | 接口地址 |
|---|---|
| 生产环境 | https://buy.itunes.apple.com/verifyReceipt |
| 沙盒环境 | https://sandbox.itunes.apple.com/verifyReceipt |
校验请求需要传递两个核心参数:receipt-data是客户端上传的原始收据字符串,password是开发者在App Store Connect中配置的共享密钥,用于验证订阅类收据的合法性。
PHP实现收据校验代码
以下是PHP实现苹果收据校验的完整代码示例,包含请求发送、结果解析、错误处理等逻辑:
<?php
/**
* 苹果支付收据校验类
*/
class ApplePayValidator
{
// 生产环境校验地址
const PRODUCTION_URL = 'https://buy.itunes.apple.com/verifyReceipt';
// 沙盒环境校验地址
const SANDBOX_URL = 'https://sandbox.itunes.apple.com/verifyReceipt';
// 共享密钥,从App Store Connect获取
private $sharedSecret;
// 是否使用沙盒环境
private $useSandbox;
public function __construct($sharedSecret, $useSandbox = false)
{
$this->sharedSecret = $sharedSecret;
$this->useSandbox = $useSandbox;
}
/**
* 校验收据
* @param string $receiptData 客户端上传的原始收据字符串
* @return array 校验结果数组
*/
public function validateReceipt($receiptData)
{
$url = $this->useSandbox ? self::SANDBOX_URL : self::PRODUCTION_URL;
// 构造请求参数
$postData = json_encode([
'receipt-data' => $receiptData,
'password' => $this->sharedSecret
]);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
// 设置超时时间
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$response = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
if ($error) {
return [
'success' => false,
'message' => '请求苹果接口失败: ' . $error
];
}
$result = json_decode($response, true);
// 状态码21007表示收据是沙盒环境的,需要切换到沙盒地址重新校验
if (isset($result['status']) && $result['status'] == 21007 && !$this->useSandbox) {
$this->useSandbox = true;
return $this->validateReceipt($receiptData);
}
return $this->parseValidationResult($result);
}
/**
* 解析苹果返回的校验结果
* @param array $result 苹果返回的校验结果
* @return array 解析后的订阅状态信息
*/
private function parseValidationResult($result)
{
if (!isset($result['status']) || $result['status'] != 0) {
return [
'success' => false,
'message' => '收据校验失败,状态码: ' . ($result['status'] ?? '未知')
];
}
$receipt = $result['receipt'] ?? [];
$latestReceiptInfo = $result['latest_receipt_info'] ?? [];
// 如果没有订阅信息,说明是普通一次性支付
if (empty($latestReceiptInfo)) {
return [
'success' => true,
'is_subscription' => false,
'receipt' => $receipt
];
}
// 处理订阅信息,取最新的订阅记录
$latestSubscription = end($latestReceiptInfo);
$currentTime = time();
$expiresDate = $latestSubscription['expires_date_ms'] / 1000;
$isAutoRenew = $result['auto_renew_status'] == 1;
return [
'success' => true,
'is_subscription' => true,
'subscription_id' => $latestSubscription['product_id'],
'expires_time' => $expiresDate,
'is_expired' => $currentTime > $expiresDate,
'is_auto_renew' => $isAutoRenew,
'latest_receipt' => $result['latest_receipt'] ?? '',
'raw_data' => $result
];
}
}
// 使用示例
$sharedSecret = 'your_shared_secret_from_app_store_connect';
$validator = new ApplePayValidator($sharedSecret, true); // 测试阶段使用沙盒环境
$receiptData = $_POST['receipt_data'] ?? ''; // 获取客户端上传的收据
$validationResult = $validator->validateReceipt($receiptData);
if ($validationResult['success']) {
if ($validationResult['is_subscription']) {
// 处理订阅逻辑
$userId = 1; // 当前用户ID
$expiresTime = $validationResult['expires_time'];
$isAutoRenew = $validationResult['is_auto_renew'];
// 这里可以将订阅信息更新到数据库,比如记录用户订阅过期时间、自动续费状态等
echo '订阅校验成功,过期时间: ' . date('Y-m-d H:i:s', $expiresTime);
} else {
echo '普通支付校验成功';
}
} else {
echo '校验失败: ' . $validationResult['message'];
}
?>
自动续费状态同步处理
除了用户主动触发收据校验之外,开发者还需要处理苹果自动续费后的状态同步,主要有两种方式:
1. 轮询校验机制
可以在数据库中记录所有订阅用户的过期时间,定期(比如每天)查询即将过期的订阅用户,重新拉取用户的收据进行校验,判断是否已经自动续费。如果校验后发现过期时间延长,说明已经完成了自动续费,更新本地的订阅状态即可。
2. App Store服务器通知
苹果提供了App Store服务器通知功能,开发者可以在App Store Connect中配置通知接收地址,当订阅状态发生变化(比如自动续费成功、用户取消订阅、退款等)时,苹果会主动推送通知到开发者的服务器,开发者接收到通知后可以直接更新对应的订阅状态,这种方式比轮询更高效也更及时。
注意事项
- 共享密钥需要妥善保管,不要泄露到客户端代码中
- 收据校验时如果返回21007状态码,需要自动切换到沙盒环境重新校验,避免测试环境的收据校验失败
- 订阅的过期时间是毫秒级时间戳,解析时需要注意单位转换
- 自动续费状态可能会被用户手动关闭,需要定期校验确认最新的自动续费状态
- 沙盒环境的测试订阅会自动快速续费,方便开发者测试自动续费逻辑,生产环境会按照实际的订阅周期续费
苹果支付的校验规则可能会更新,开发过程中建议定期查看苹果官方的订阅校验文档,确保逻辑符合最新的规范要求。
PHP苹果支付自动续费App_Store_Receipt_Validation修改时间:2026-07-06 03:54:30