Lim*_*Jee 4 in-app-purchase ios in-app-purchase-receipt
我正在尝试使用应用商店通知设置我的服务器。\n以便当用户退款应用内购买时我可以收到通知。\n https://developer.apple.com/documentation/appstoreservernotifications/receiving_app_store_server_notifications <- 指南我现在正在寻找。
\nThe version 2 response body, responseBodyV2, contains a signedPayload that\xe2\x80\x99s cryptographically signed by the App Store in JSON Web Signature (JWS) format. The JWS format increases security and enables you to decode and validate the signature on your server. The notification data contains transaction and subscription renewal information that the App Store signs in JWS. The App Store Server API and the StoreKit In-App Purchase API use the same JWS-signed format for transaction and subscription status information. For more information about JWS, see the IETF RFC 7515 specification.\nRun Code Online (Sandbox Code Playgroud)\n根据文章,似乎我必须在与 App Store Connect 共享的 url 中保存签名的有效负载代码。\n https://gist.github.com/atpons/5279af568cb7d1b101247c02f0a022af \n<- 思考代码会看起来像这样
\n所以我的问题是,
我是否需要制作一些新的私钥并与服务器开发人员共享?\n看起来我们从此处存储密钥https://www.apple.com/certificateauthority/\n并在我们请求时使用它?\n我如何收到通知?\n我是否应该期望\n预期的响应json结构\n这种通知将到达我与我的App Store Connect共享的url。\n感谢您阅读我的问题!
\n小智 5
我按照以下步骤操作:
import { X509Certificate } from 'crypto'
import fs from 'fs'
import jwt from 'jsonwebtoken'
// parameter
const signedPayloadFile = 'path to signedPayload file, ex: /home/vannguyen/signedPayload.txt'
const appleRootPemFile = 'path to pem file in step 2, ex: /home/vannguyen/apple_root.pem'
// end
const signedPayload = fs.readFileSync(signedPayloadFile).toString()
const decodeToken = (token, segment) => {
const tokenDecodablePart = token.split('.')[segment]
const decoded = Buffer.from(tokenDecodablePart, 'base64').toString()
return decoded
}
const { alg, x5c } = JSON.parse(decodeToken(signedPayload, 0))
const x5cCertificates = x5c.map(
(header) => new X509Certificate(Buffer.from(header, 'base64'))
)
const appleRootCertificate = new X509Certificate(
fs.readFileSync(appleRootPemFile)
)
const checkIssued = appleRootCertificate.checkIssued(
x5cCertificates[x5cCertificates.length - 1]
)
if (!checkIssued) {
throw new Error('Invalid token')
}
x5cCertificates.push(appleRootCertificate)
const verifierStatuses = x5cCertificates.map((x590, index) => {
if (index >= x5cCertificates.length - 1) return true
return x590.verify(x5cCertificates[index + 1].publicKey)
})
if (verifierStatuses.includes(false)) {
throw new Error('Invalid token')
}
const { publicKey } = x5cCertificates[0]
const payload = JSON.parse(decodeToken(signedPayload, 1))
const transactionInfo = jwt.verify(
payload.data.signedTransactionInfo,
publicKey,
{
algorithms: alg
}
)
console.log('transactionInfo: ', transactionInfo)
const transactionRenewalInfo = jwt.verify(
payload.data.signedRenewalInfo,
publicKey,
{
algorithms: alg
}
)
console.log('transactionRenewalInfo: ', transactionRenewalInfo)Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2922 次 |
| 最近记录: |