Created
March 11, 2025 10:06
-
-
Save jeiea/f87a1f1f231f3a6526a4ad473cd66f29 to your computer and use it in GitHub Desktop.
For deno
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// see https://www.npmjs.com/package/node-apple-receipt-verify#configoptions-object | |
// https://medium.com/axel-springer-tech/debugging-and-reading-apple-receipts-2e47f9793f74 | |
import { parseArgs } from "jsr:@std/cli/parse-args"; | |
import { config as appleReceiptVerifyConfig, validate } from "npm:node-apple-receipt-verify"; | |
const params = { | |
string: ["environment"], | |
boolean: ["ignoreExpired", "extended", "verbose", "ignoreExpiredError", "excludeOldTransactions"], | |
alias: { | |
p: "environment", | |
ie: "ignoreExpired", | |
ee: "extended", | |
e: "verbose", | |
iee: "ignoreExpiredError", | |
eot: "excludeOldTransactions", | |
}, | |
default: { | |
environment: "production,sandbox", | |
ignoreExpired: false, | |
extended: false, | |
verbose: true, | |
ignoreExpiredError: false, | |
excludeOldTransactions: false, | |
}, | |
} as const; | |
const { _: [filePath], ...args } = parseArgs(Deno.args, params); | |
if (typeof filePath !== "string") { | |
console.log( | |
"Usage: deno run --allow-read --allow-env verify.ts <receipt file path>{ <optionalFlag>}\n", | |
); | |
console.log( | |
"Optional flags (see https://www.npmjs.com/package/node-apple-receipt-verify#configoptions-object):", | |
); | |
for (const key of [...params.string, ...params.boolean]) { | |
const alias = Object.keys(params.alias).find((k) => | |
params.alias[k as keyof typeof params.alias] === key | |
); | |
console.log(` ${alias}, ${key}, default=${params.default[key]}, set=${args[key]}`); | |
} | |
console.log( | |
"\nPrecondition: Set APP_STORE_SHARED_SECRET environment variable with your shared secret\n", | |
); | |
Deno.exit(1); | |
} | |
const sharedSecret = Deno.env.get("APP_STORE_SHARED_SECRET"); | |
if (!sharedSecret) { | |
console.error("Error: APP_STORE_SHARED_SECRET environment variable is not set"); | |
Deno.exit(1); | |
} | |
const receiptData = await Deno.readTextFile(filePath); | |
const config = { | |
secret: sharedSecret, | |
...Object.fromEntries(Object.values(params.alias).map((name) => [name, args[name]])), | |
environment: args.environment.split(","), | |
}; | |
appleReceiptVerifyConfig(config); | |
try { | |
const validatedData = await validate({ receipt: receiptData }); | |
for (const data of validatedData) { | |
const expirationMs = parseInt(data.expirationDate); | |
data.expirationDateString = new Date(expirationMs).toLocaleString(); | |
const purchaseMs = parseInt(data.purchaseDate); | |
data.purchaseDateString = new Date(purchaseMs).toLocaleString(); | |
} | |
console.log(validatedData); | |
} catch (error) { | |
console.error(error); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment