Apple 内购IAP

本文详细介绍了iOS应用内购买(IAP)的验证过程,包括客户端下单、支付成功后发送票据到服务器以及服务器如何校验。客户端使用Unity插件接收的格式为Base64编码的Payload,服务器通过Apple的API进行验单,返回结果中的status字段用于判断验证是否成功。验单失败的常见错误代码和含义也进行了说明。此外,强调了transaction_id的重要性和双重验证的必要性,以防止重复校验。
摘要由CSDN通过智能技术生成

1:客户端传tradeid(商品ID)来服务器下单,下单成功之后服务器告诉客户端下单成功了,

2:客户端拉起支付是需要productid(com.kx880.XXXXXXXXX)

支付成功之后 会收到票据,客户端把票据发给服务器,服务器再去苹果校验

客户端是用的unity的插件收到的格式如下

{"Payload":"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","Store":"AppleAppStore","TransactionID":"2000000081353285"}

这个Payload就是已经base64之后的结果,这个发给服务器 服务器去校验就好了

transid 是com.kx880.devilhunter.101XXXXX

def verifyReceipt(self,uid,orderid,transid,receiptStr,sandbox = 0,password = None):
    logging.debug("uid=%s verifyReceipt orderid=%s transid=%s sandbox=%s",uid,orderid,transid,sandbox)
    url = self.buy_url if sandbox == 0 else self.sandbox_url
    # receiptBase64 = base64.standard_b64encode(receiptStr)
    receiptBase64 = receiptStr
    jsonReceipt = json.dumps({"receipt-data" : receiptBase64,"password":password}) if password else json.dumps({"receipt-data" : receiptBase64})
    agent = Agent(reactor, connectTimeout = 10)
    d = agent.request(method = b'POST',uri = url,headers = Headers({'Content-type':["application/json"]}),bodyProducer = StringProducer(jsonReceipt.encode(self.encoding)))
    d.addCallback(self.cbRequest, jsonReceipt)
    d.addErrback(self.cbError, jsonReceipt)
AppleIapGate cbBody body:{u'status': 21002}
AppleIapGate cbBody body:{u'environment': u'Sandbox', u'status': 0, u'receipt': {u'download_id': 0, u'adam_id': 0, u'request_date': u'2022-06-16 08:36:37 Etc/GMT', u'app_item_id': 0, u'original_purchase_date_pst': u'2013-08-01 00:00:00 America/Los_Angeles', u'version_external_identifier': 0, u'receipt_creation_date': u'2022-06-16 08:36:30 Etc/GMT', u'in_app': [{u'is_trial_period': u'false', u'purchase_date_pst': u'2022-06-16 01:36:30 America/Los_Angeles', u'product_id': u'com.kx880.devilhunter.1016101', u'original_transaction_id': u'2000000081374113', u'original_purchase_date_pst': u'2022-06-16 01:36:30 America/Los_Angeles', u'in_app_ownership_type': u'PURCHASED', u'original_purchase_date': u'2022-06-16 08:36:30 Etc/GMT', u'original_purchase_date_ms': u'1655368590000', u'purchase_date': u'2022-06-16 08:36:30 Etc/GMT', u'purchase_date_ms': u'1655368590000', u'transaction_id': u'2000000081374113', u'quantity': u'1'}], u'original_purchase_date_ms': u'1375340400000', u'original_application_version': u'1.0', u'original_purchase_date': u'2013-08-01 07:00:00 Etc/GMT', u'request_date_ms': u'1655368597680', u'bundle_id': u'com.kx880.devilhunter', u'receipt_creation_date_pst': u'2022-06-16 01:36:30 America/Los_Angeles', u'application_version': u'0', u'request_date_pst': u'2022-06-16 01:36:37 America/Los_Angeles', u'receipt_creation_date_ms': u'1655368590000', u'receipt_type': u'ProductionSandbox'}}

 根据返回结果中status判断是否成功

'''
  * 0     验单成功
  * 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环境的验证服务
'''

客户端需要 transaction_id 去appstore消单,服务器也要记录这个数据,防止客户端重复校验。。。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值