<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Apple内购 on yuqiuwen</title><link>https://yuqiuwen.github.io/tags/apple%E5%86%85%E8%B4%AD/</link><description>Recent content in Apple内购 on yuqiuwen</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Thu, 28 Nov 2024 00:00:00 +0000</lastBuildDate><atom:link href="https://yuqiuwen.github.io/tags/apple%E5%86%85%E8%B4%AD/index.xml" rel="self" type="application/rss+xml"/><item><title>Apple内购验签流程</title><link>https://yuqiuwen.github.io/p/apple-iap-receipt/</link><pubDate>Thu, 28 Nov 2024 00:00:00 +0000</pubDate><guid>https://yuqiuwen.github.io/p/apple-iap-receipt/</guid><description>&lt;p&gt;&lt;strong&gt;验证项：&lt;/strong&gt;&lt;br&gt;&#10;针对旧版验证api：https://developer.apple.com/documentation/appstorereceipts/verifyreceipt&#10;为了验证收据伪造等情况，需验证以下几点：&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;receipt.environment，区分订单环境（生产或沙盒），若返回21007表示沙盒环境，此时需用沙盒api再次验证https://sandbox.itunes.apple.com/verifyReceipt，方便客户端在生产环境进行测试而不用来回切换环境&lt;/li&gt;&#10;&lt;li&gt;receipt.status == 0，为0表示有效&lt;/li&gt;&#10;&lt;li&gt;order.product_id in product，系统中商品是否存在&lt;/li&gt;&#10;&lt;li&gt;receipt.product_id == order.product_id，收据返回的商品id是否和订单的商品id一致&lt;/li&gt;&#10;&lt;li&gt;receipt.bundle_id == product.bundle_id，不同bundle_id之间的product_id可能重复，若有多个包，系统可单独管理内购商品，此时订单中的product_id应该为product表的主键id&lt;/li&gt;&#10;&lt;li&gt;receipt.transaction_id，检查商户id是否已存在于订单记录中，若存在表示已验签，可将 (pay_type, transaction_id) 作为联合唯一索引&lt;/li&gt;&#10;&lt;li&gt;receipt.cancellation_date，如果receipt中包含cancellation_date属性，说明交易被取消或退款&lt;/li&gt;&#10;&lt;li&gt;order.ctime &amp;lt; receipt.purchase_date_ms，正常情况应该是下单时间小于收据中的购买时间，前提是系统时间order.ctime准确无误&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;&lt;strong&gt;流程图：&lt;/strong&gt;&lt;/p&gt;&#10;&lt;pre class="mermaid" style="visibility:hidden"&gt;sequenceDiagram&#10; actor Client&#10; participant Server&#10; participant Apple Server&#10; participant MQ&#10;&#10; &#10; Client -&gt;&gt; Server: query product info&#10; Server -&gt;&gt; Client: return product&#10; Client -&gt;&gt;+ Server: request orderId&#10; Server -&gt;&gt; Server: create order&#10; Server -&gt;&gt; MQ: send delay message (check order state after 15 min)&#10; Server -&gt;&gt;- Client: return orderId&#10; Client -&gt;&gt;+ Apple Server: pay&#10; Apple Server -&gt;&gt;- Client: return receipt&#10; Client -&gt;&gt;+ Server: verify&#10; Server -&gt;&gt; Server: query order&#10;&#10; alt not exists ?&#10; Server -&gt;&gt; Client: return error&#10; else exists&#10; Server -&gt;&gt;- Apple Server: verify receipt&#10; Apple Server -&gt;&gt; Server: return result&#10; alt passed&#10; Server -&gt;&gt; Client: return success&#10; else else&#10; Server -&gt;&gt; Client: return failed&#10; end&#10; end&#10; &#10; MQ -&gt;&gt;+ Server: deliver message&#10; Server -&gt;&gt; Server: check order state&#10; alt unpaid&#10; Server -&gt;&gt;- Server: marked as canceled&#10; end&#10; &lt;/pre&gt;</description></item></channel></rss>