PHP处理苹果APP内购后到服务端的二次验证

时间:2021-07-28 09:12:12

一、苹果APP支付到服务端验证整体流程

1. 用户在app中点击购买;

2. app调用服务端接口生成订单;

3. app获取到服务端订单生成成功后弹出支付窗口;

4. 用户输入密码支付;

5. app接收支付后apple应用商店返回的支付凭证;

6. app将支付凭证传回服务器,调用服务器接口验证凭证是否有效;

7. app获取服务器端的验证结果,反馈用户支付结果状态。

说明:苹果支付的商品,需要先在 itunes Connect 中配置APP内购项目,配置后对应会生成一个商品ID,在苹果APP端调用苹果支付时,就需要给苹果商店传送这个商品ID(product_id)参数。然后支付过程是在苹果商店中进行,支付完成后,返回一个支付凭证给APP,表示支付完成,但一般会再次调用自己的服务器(商家服务器)端进行支付验证,这时候在服务器写个验证接口,判断凭证是否有效,如果有效,对应修改订单状态和购买的商品状态等等。

StoreKit、您的应用程序、App Store 和您的服务器之间在交易期间发生的交互图。

built-in-product-delivery2from-developer

store_transactionsfrom-developer

二、验证代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

/**

 * 验证数据并更新余额

 * @param array $params

 * @return bool

 * @throws BadRequestHttpException

 * @author: luwc

 * @Time: 2021/7/27 15:35

 */

public static function verifyOrder(array $params = [])

{

    $user_id $params['user_id'];// 用户ID 

    $apple_receipt $params['apple_receipt']; // 付款后凭证

    $order_no $params['order_no'];// 获取订单号

     

    $verify = self::validate_apple_pay($apple_receipt$params);

    if ($verify['status'] !== true) {

        throw new BadRequestHttpException('验证失败:' $verify['message'], 400);

    }

    // todu 其他逻辑

}

/**

 * 验证AppStore内付

 * @param $receipt_data 付款后凭证

 * @param array $params 其他参数

 * @return array 验证是否成功

 * @author: luwc

 * @Time: 2021/7/27 15:00

 */

private static function validate_apple_pay($receipt_data$params = [])

{

    // 验证参数

    if (strlen($receipt_data) < 20) {

        $result array(

            'status' => false,

            'message' => '非法参数'

        );

        return $result;

    }

    // 请求验证

    $html = self::acurl($receipt_data);

    $data = json_decode($html, true);

    // 如果是沙盒数据 则验证沙盒模式

    if ($data['status'] == '21007') {

        // 请求验证

        $html = self::acurl($receipt_data, 1);

        $data = json_decode($html, true);

        $data['sandbox'] = '1';

    }

    if (isset($params['debug'])) {

        exit(json_encode($data));

    }

    // 判断是否购买成功

    if (intval($data['status']) === 0) {

        $result array(

            'status' => true,

            'message' => ''

        );

    else {

        $result array(

            'status' => false,

            'message' => 'status:' $data['status']

        );

    }

    return $result;

}

/**

 * 21000 App Store不能读取你提供的JSON对象

 * 21002 receipt-data域的数据有问题

 * 21003 receipt无法通过验证

 * 21004 提供的shared secret不匹配你账号中的shared secret

 * 21005 receipt服务器当前不可用

 * 21006 receipt合法,但是订阅已过期。服务器接收到这个状态码时,receipt数据仍然会解码并一起发送

 * 21007 receipt是Sandbox receipt,但却发送至生产系统的验证服务

 * 21008 receipt是生产receipt,但却发送至Sandbox环境的验证服务

 */

private static function acurl($receipt_data$sandbox = 0)

{

    //小票信息

    $secret "xxxxxxx";    // APP共享密钥,在itunes中获取

    $POSTFIELDS = ["receipt-data" => $receipt_data'password' => $secret];

    $POSTFIELDS = json_encode($POSTFIELDS);

    //正式购买地址 沙盒购买地址

    $url_buy "https://buy.itunes.apple.com/verifyReceipt";

    $url_sandbox "https://sandbox.itunes.apple.com/verifyReceipt";

    $url $sandbox $url_sandbox $url_buy;

    //简单的curl

    $ch = curl_init($url);

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

    curl_setopt($ch, CURLOPT_POST, 1);

    curl_setopt($ch, CURLOPT_POSTFIELDS, $POSTFIELDS);

    $result = curl_exec($ch);

    curl_close($ch);

    return $result;

}

三、验证说明:

选择验证技术

有两种方法可以验证收据的真实性:

  • 本地、设备上的收据验证,最适合验证具有应用内购买功能的应用的收据签名

  • 使用 App Store 进行服务器端收据验证,最适合持久化应用内购买以维护和管理购买记录

比较这些方法并确定最适合您的应用程序和基础架构的方法。您也可以选择实施这两种方法。

如果需要,维护和管理服务器上的消耗品记录。

在您致电 之前,应用内购买的消耗品会保留在收据中。非消耗品、自动续订订阅项目和非续订订阅项目无限期地保留在收据中。对于自动续订订阅管理,请参阅下表,了解服务器端收据验证相对于设备上收据验证的主要优势。finishTransaction(_:)

Choosing a receipt validation technique | Apple Developer Documentation

服务端验证:将收据数据发送到 App Store

在您的服务器上,使用receipt-datapassword如果收据包含自动更新订阅)和 中exclude-old-transactions详述的密钥创建一个 JSON 对象。requestBody

将此 JSON 对象作为 HTTP POST 请求的负载提交。在沙箱中测试您的应用程序以及您的应用程序正在审核中时,请使用测试环境 URL 。当您的应用在 App Store 上线时使用生产 URL 。有关这些端点的更多信息,请参阅verifyReceipthttps://sandbox.itunes.apple.com/verifyReceipthttps://buy.itunes.apple.com/verifyReceipt

Validating receipts with the App Store | Apple Developer Documentation

requestBody官方示例:

图片.png

requestBody | Apple Developer Documentation


 

四、参考文档

1. 苹果内购买项目配置流程

2. http://www.cnblogs.com/zhaoqingqing/p/4589200.html

3. https://www.cnblogs.com/zhaoqingqing/p/4597794.html

4. iOS应用内支付(IAP)详解

  • 20
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值