@arcblock/payment-service 1.29.5 → 1.29.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cf.js +67 -217
- package/dist/index.js +292 -42
- package/package.json +3 -5
package/dist/index.js
CHANGED
|
@@ -9140,17 +9140,230 @@ var init_apple_root_certs = __esm({
|
|
|
9140
9140
|
}
|
|
9141
9141
|
});
|
|
9142
9142
|
|
|
9143
|
-
// ../../blocklets/core/api/src/integrations/app-store/
|
|
9144
|
-
|
|
9145
|
-
const
|
|
9146
|
-
|
|
9147
|
-
|
|
9148
|
-
|
|
9149
|
-
const
|
|
9150
|
-
|
|
9151
|
-
|
|
9152
|
-
|
|
9143
|
+
// ../../blocklets/core/api/src/integrations/app-store/native-asn1.ts
|
|
9144
|
+
function oidToDerTag(oid) {
|
|
9145
|
+
const parts = oid.split(".").map((p) => Number.parseInt(p, 10));
|
|
9146
|
+
if (parts.length < 2 || parts.some((n) => !Number.isInteger(n) || n < 0)) {
|
|
9147
|
+
throw new Error(`oidToDerTag: invalid OID "${oid}"`);
|
|
9148
|
+
}
|
|
9149
|
+
const content = [40 * parts[0] + parts[1]];
|
|
9150
|
+
for (let i = 2; i < parts.length; i++) {
|
|
9151
|
+
let v = parts[i];
|
|
9152
|
+
const sevenBitGroups = [v & 127];
|
|
9153
|
+
v = Math.floor(v / 128);
|
|
9154
|
+
while (v > 0) {
|
|
9155
|
+
sevenBitGroups.unshift(v & 127 | 128);
|
|
9156
|
+
v = Math.floor(v / 128);
|
|
9157
|
+
}
|
|
9158
|
+
content.push(...sevenBitGroups);
|
|
9159
|
+
}
|
|
9160
|
+
if (content.length > 127) {
|
|
9161
|
+
throw new Error(`oidToDerTag: OID "${oid}" content too long for single-byte length`);
|
|
9162
|
+
}
|
|
9163
|
+
return Buffer.from([6, content.length, ...content]);
|
|
9164
|
+
}
|
|
9165
|
+
function certHasOid(cert, oid) {
|
|
9166
|
+
return Buffer.from(cert.raw).includes(oidToDerTag(oid));
|
|
9167
|
+
}
|
|
9168
|
+
var init_native_asn1 = __esm({
|
|
9169
|
+
"../../blocklets/core/api/src/integrations/app-store/native-asn1.ts"() {
|
|
9170
|
+
"use strict";
|
|
9171
|
+
}
|
|
9172
|
+
});
|
|
9173
|
+
|
|
9174
|
+
// ../../blocklets/core/api/src/integrations/app-store/native-jws.ts
|
|
9175
|
+
function base64UrlToJson(segment, code) {
|
|
9176
|
+
let text;
|
|
9177
|
+
try {
|
|
9178
|
+
text = Buffer.from(segment, "base64url").toString("utf8");
|
|
9179
|
+
} catch {
|
|
9180
|
+
throw new AppleJwsVerifyError(code, "segment is not valid base64url");
|
|
9181
|
+
}
|
|
9182
|
+
let parsed;
|
|
9183
|
+
try {
|
|
9184
|
+
parsed = JSON.parse(text);
|
|
9185
|
+
} catch {
|
|
9186
|
+
throw new AppleJwsVerifyError(code, "segment is not valid JSON");
|
|
9187
|
+
}
|
|
9188
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
9189
|
+
throw new AppleJwsVerifyError(code, "segment is not a JSON object");
|
|
9190
|
+
}
|
|
9191
|
+
const out = parsed;
|
|
9192
|
+
for (const key of ["__proto__", "constructor", "prototype"]) {
|
|
9193
|
+
if (Object.prototype.hasOwnProperty.call(out, key)) {
|
|
9194
|
+
delete out[key];
|
|
9195
|
+
}
|
|
9196
|
+
}
|
|
9197
|
+
return out;
|
|
9198
|
+
}
|
|
9199
|
+
function buildCert(b64, label) {
|
|
9200
|
+
try {
|
|
9201
|
+
return new import_node_crypto.X509Certificate(Buffer.from(b64, "base64"));
|
|
9202
|
+
} catch {
|
|
9203
|
+
throw new AppleJwsVerifyError("MALFORMED_CERT", `${label} cert is not valid DER`);
|
|
9204
|
+
}
|
|
9205
|
+
}
|
|
9206
|
+
function assertCertValid(cert, effectiveDate, label) {
|
|
9207
|
+
const validFrom = Date.parse(cert.validFrom);
|
|
9208
|
+
const validTo = Date.parse(cert.validTo);
|
|
9209
|
+
if (Number.isNaN(validFrom) || Number.isNaN(validTo)) {
|
|
9210
|
+
throw new AppleJwsVerifyError("CERT_VALIDITY", `${label} cert has unparseable validity dates`);
|
|
9211
|
+
}
|
|
9212
|
+
if (validFrom > effectiveDate + MAX_SKEW_MS) {
|
|
9213
|
+
throw new AppleJwsVerifyError("CERT_NOT_YET_VALID", `${label} cert not valid until after signedDate`);
|
|
9214
|
+
}
|
|
9215
|
+
if (validTo < effectiveDate - MAX_SKEW_MS) {
|
|
9216
|
+
throw new AppleJwsVerifyError("CERT_EXPIRED", `${label} cert expired before signedDate`);
|
|
9217
|
+
}
|
|
9218
|
+
}
|
|
9219
|
+
async function verifyAppleJws(jws, opts = {}) {
|
|
9220
|
+
const trustedRoots = opts.trustedRoots ?? APPLE_ROOT_CERTS;
|
|
9221
|
+
const parts = jws.split(".");
|
|
9222
|
+
if (parts.length !== 3) {
|
|
9223
|
+
throw new AppleJwsVerifyError("FORMAT", "expected 3 JWS segments");
|
|
9224
|
+
}
|
|
9225
|
+
const [headerSeg, payloadSeg, signatureSeg] = parts;
|
|
9226
|
+
const header = base64UrlToJson(headerSeg, "HEADER");
|
|
9227
|
+
if (header.alg !== "ES256") {
|
|
9228
|
+
throw new AppleJwsVerifyError("ALG", "only ES256 is accepted");
|
|
9229
|
+
}
|
|
9230
|
+
if (!Array.isArray(header.x5c) || header.x5c.length !== 3) {
|
|
9231
|
+
throw new AppleJwsVerifyError("INVALID_CHAIN_LENGTH", "x5c must contain exactly 3 certs");
|
|
9232
|
+
}
|
|
9233
|
+
const leaf = buildCert(header.x5c[0], "leaf");
|
|
9234
|
+
const intermediate = buildCert(header.x5c[1], "intermediate");
|
|
9235
|
+
const rootFromJws = buildCert(header.x5c[2], "root");
|
|
9236
|
+
const rootDer = Buffer.from(rootFromJws.raw);
|
|
9237
|
+
const anchored = trustedRoots.some((trusted) => trusted.equals(rootDer));
|
|
9238
|
+
if (!anchored) {
|
|
9239
|
+
throw new AppleJwsVerifyError("ANCHOR", "presented root is not a trusted Apple root");
|
|
9240
|
+
}
|
|
9241
|
+
if (!intermediate.verify(rootFromJws.publicKey) || intermediate.issuer !== rootFromJws.subject) {
|
|
9242
|
+
throw new AppleJwsVerifyError("CHAIN", "intermediate does not chain to root");
|
|
9243
|
+
}
|
|
9244
|
+
if (!leaf.verify(intermediate.publicKey) || leaf.issuer !== intermediate.subject) {
|
|
9245
|
+
throw new AppleJwsVerifyError("CHAIN", "leaf does not chain to intermediate");
|
|
9246
|
+
}
|
|
9247
|
+
if (intermediate.ca !== true || !certHasOid(intermediate, APPLE_INTERMEDIATE_OID)) {
|
|
9248
|
+
throw new AppleJwsVerifyError("OID", "intermediate missing CA flag or Apple OID");
|
|
9249
|
+
}
|
|
9250
|
+
if (!certHasOid(leaf, APPLE_LEAF_OID)) {
|
|
9251
|
+
throw new AppleJwsVerifyError("OID", "leaf missing Apple OID");
|
|
9252
|
+
}
|
|
9253
|
+
const payload = base64UrlToJson(payloadSeg, "PAYLOAD");
|
|
9254
|
+
const effectiveDate = opts.signedDate ?? (typeof payload.signedDate === "number" ? payload.signedDate : void 0);
|
|
9255
|
+
if (typeof effectiveDate !== "number") {
|
|
9256
|
+
throw new AppleJwsVerifyError("NO_SIGNED_DATE", "payload has no numeric signedDate to validate against");
|
|
9257
|
+
}
|
|
9258
|
+
assertCertValid(leaf, effectiveDate, "leaf");
|
|
9259
|
+
assertCertValid(intermediate, effectiveDate, "intermediate");
|
|
9260
|
+
assertCertValid(rootFromJws, effectiveDate, "root");
|
|
9261
|
+
const spki = leaf.publicKey.export({ type: "spki", format: "der" });
|
|
9262
|
+
const key = await crypto.subtle.importKey(
|
|
9263
|
+
"spki",
|
|
9264
|
+
spki,
|
|
9265
|
+
{ name: "ECDSA", namedCurve: "P-256" },
|
|
9266
|
+
false,
|
|
9267
|
+
["verify"]
|
|
9268
|
+
);
|
|
9269
|
+
const signature = Buffer.from(signatureSeg, "base64url");
|
|
9270
|
+
const signingInput = Buffer.from(`${headerSeg}.${payloadSeg}`, "ascii");
|
|
9271
|
+
const valid = await crypto.subtle.verify({ name: "ECDSA", hash: "SHA-256" }, key, signature, signingInput);
|
|
9272
|
+
if (!valid) {
|
|
9273
|
+
throw new AppleJwsVerifyError("SIGNATURE", "ES256 signature does not verify against the leaf key");
|
|
9274
|
+
}
|
|
9275
|
+
return payload;
|
|
9276
|
+
}
|
|
9277
|
+
var import_node_crypto, APPLE_LEAF_OID, APPLE_INTERMEDIATE_OID, MAX_SKEW_MS, AppleJwsVerifyError;
|
|
9278
|
+
var init_native_jws = __esm({
|
|
9279
|
+
"../../blocklets/core/api/src/integrations/app-store/native-jws.ts"() {
|
|
9280
|
+
"use strict";
|
|
9281
|
+
import_node_crypto = require("node:crypto");
|
|
9282
|
+
init_apple_root_certs();
|
|
9283
|
+
init_native_asn1();
|
|
9284
|
+
APPLE_LEAF_OID = "1.2.840.113635.100.6.11.1";
|
|
9285
|
+
APPLE_INTERMEDIATE_OID = "1.2.840.113635.100.6.2.1";
|
|
9286
|
+
MAX_SKEW_MS = 6e4;
|
|
9287
|
+
AppleJwsVerifyError = class extends Error {
|
|
9288
|
+
constructor(code, detail) {
|
|
9289
|
+
super(detail ? `AppStore JWS verify failed [${code}]: ${detail}` : `AppStore JWS verify failed [${code}]`);
|
|
9290
|
+
this.name = "AppleJwsVerifyError";
|
|
9291
|
+
this.code = code;
|
|
9292
|
+
}
|
|
9293
|
+
};
|
|
9294
|
+
}
|
|
9295
|
+
});
|
|
9296
|
+
|
|
9297
|
+
// ../../blocklets/core/api/src/integrations/app-store/native-api.ts
|
|
9298
|
+
function pemToDer(pem) {
|
|
9299
|
+
const body = pem.replace(/-----BEGIN [^-]+-----/g, "").replace(/-----END [^-]+-----/g, "").replace(/\s+/g, "");
|
|
9300
|
+
if (!body) {
|
|
9301
|
+
throw new Error("AppStore API: private_key_pem is empty or not PEM-armored");
|
|
9302
|
+
}
|
|
9303
|
+
return Buffer.from(body, "base64");
|
|
9304
|
+
}
|
|
9305
|
+
async function signBearerJwt(creds) {
|
|
9306
|
+
const header = { alg: "ES256", kid: creds.keyId, typ: "JWT" };
|
|
9307
|
+
const iat = Math.floor(Date.now() / 1e3);
|
|
9308
|
+
const payload = {
|
|
9309
|
+
iss: creds.issuerId,
|
|
9310
|
+
iat,
|
|
9311
|
+
exp: iat + JWT_TTL_SECONDS,
|
|
9312
|
+
aud: "appstoreconnect-v1",
|
|
9313
|
+
bid: creds.bundleId
|
|
9314
|
+
};
|
|
9315
|
+
const headerB64 = Buffer.from(JSON.stringify(header)).toString("base64url");
|
|
9316
|
+
const payloadB64 = Buffer.from(JSON.stringify(payload)).toString("base64url");
|
|
9317
|
+
const signingInput = `${headerB64}.${payloadB64}`;
|
|
9318
|
+
let key;
|
|
9319
|
+
try {
|
|
9320
|
+
key = await crypto.subtle.importKey(
|
|
9321
|
+
"pkcs8",
|
|
9322
|
+
pemToDer(creds.privateKeyPem),
|
|
9323
|
+
{ name: "ECDSA", namedCurve: "P-256" },
|
|
9324
|
+
false,
|
|
9325
|
+
["sign"]
|
|
9326
|
+
);
|
|
9327
|
+
} catch {
|
|
9328
|
+
throw new Error("AppStore API: private_key_pem is not a valid EC P-256 PKCS#8 key");
|
|
9329
|
+
}
|
|
9330
|
+
const signature = await crypto.subtle.sign(
|
|
9331
|
+
{ name: "ECDSA", hash: "SHA-256" },
|
|
9332
|
+
key,
|
|
9333
|
+
Buffer.from(signingInput, "ascii")
|
|
9334
|
+
);
|
|
9335
|
+
return `${signingInput}.${Buffer.from(signature).toString("base64url")}`;
|
|
9336
|
+
}
|
|
9337
|
+
async function nativeGetAllSubscriptionStatuses(originalTransactionId, creds) {
|
|
9338
|
+
if (!creds.issuerId || !creds.keyId || !creds.privateKeyPem) {
|
|
9339
|
+
throw new Error("AppStore API: issuer_id/key_id/private_key_pem are required");
|
|
9340
|
+
}
|
|
9341
|
+
const host = creds.environment === "production" ? API_HOST_PRODUCTION : API_HOST_SANDBOX;
|
|
9342
|
+
const url = `${host}/inApps/v1/subscriptions/${encodeURIComponent(originalTransactionId)}`;
|
|
9343
|
+
const jwt = await signBearerJwt(creds);
|
|
9344
|
+
const response = await fetch(url, {
|
|
9345
|
+
method: "GET",
|
|
9346
|
+
headers: { Authorization: `Bearer ${jwt}`, Accept: "application/json" }
|
|
9347
|
+
});
|
|
9348
|
+
if (response.status === 404) {
|
|
9349
|
+
return { data: [] };
|
|
9350
|
+
}
|
|
9351
|
+
if (!response.ok) {
|
|
9352
|
+
throw new Error(`AppStore API: getAllSubscriptionStatuses failed with HTTP ${response.status}`);
|
|
9353
|
+
}
|
|
9354
|
+
return await response.json();
|
|
9153
9355
|
}
|
|
9356
|
+
var API_HOST_PRODUCTION, API_HOST_SANDBOX, JWT_TTL_SECONDS;
|
|
9357
|
+
var init_native_api = __esm({
|
|
9358
|
+
"../../blocklets/core/api/src/integrations/app-store/native-api.ts"() {
|
|
9359
|
+
"use strict";
|
|
9360
|
+
API_HOST_PRODUCTION = "https://api.storekit.apple.com";
|
|
9361
|
+
API_HOST_SANDBOX = "https://api.storekit-sandbox.apple.com";
|
|
9362
|
+
JWT_TTL_SECONDS = 300;
|
|
9363
|
+
}
|
|
9364
|
+
});
|
|
9365
|
+
|
|
9366
|
+
// ../../blocklets/core/api/src/integrations/app-store/signed-data-verifier.ts
|
|
9154
9367
|
function isSignatureVerificationSkipped() {
|
|
9155
9368
|
if (!appStoreSkipSignatureVerify()) return false;
|
|
9156
9369
|
if (isProduction()) {
|
|
@@ -9161,21 +9374,19 @@ function isSignatureVerificationSkipped() {
|
|
|
9161
9374
|
}
|
|
9162
9375
|
return true;
|
|
9163
9376
|
}
|
|
9164
|
-
async function verifySignedTransaction(signedTransaction,
|
|
9377
|
+
async function verifySignedTransaction(signedTransaction, _bundleId, _environment) {
|
|
9165
9378
|
if (isSignatureVerificationSkipped()) {
|
|
9166
9379
|
logger_default.warn("app_store: signature verification skipped via APP_STORE_SKIP_SIGNATURE_VERIFY");
|
|
9167
9380
|
return decodeUnsafe(signedTransaction);
|
|
9168
9381
|
}
|
|
9169
|
-
|
|
9170
|
-
return verifier.verifyAndDecodeTransaction(signedTransaction);
|
|
9382
|
+
return verifyAppleJws(signedTransaction);
|
|
9171
9383
|
}
|
|
9172
|
-
async function verifySignedNotification(signedPayload,
|
|
9384
|
+
async function verifySignedNotification(signedPayload, _bundleId, _environment) {
|
|
9173
9385
|
if (isSignatureVerificationSkipped()) {
|
|
9174
9386
|
logger_default.warn("app_store: signature verification skipped via APP_STORE_SKIP_SIGNATURE_VERIFY");
|
|
9175
9387
|
return decodeUnsafe(signedPayload);
|
|
9176
9388
|
}
|
|
9177
|
-
|
|
9178
|
-
return verifier.verifyAndDecodeNotification(signedPayload);
|
|
9389
|
+
return verifyAppleJws(signedPayload);
|
|
9179
9390
|
}
|
|
9180
9391
|
function decodeUnsafe(jws) {
|
|
9181
9392
|
const parts = jws.split(".");
|
|
@@ -9188,41 +9399,85 @@ function decodeUnsafe(jws) {
|
|
|
9188
9399
|
throw new Error(`AppStore JWS payload not valid JSON: ${err.message}`);
|
|
9189
9400
|
}
|
|
9190
9401
|
}
|
|
9191
|
-
async function getApiClient(creds) {
|
|
9192
|
-
const key = `${creds.bundleId}:${creds.environment}:${creds.keyId}`;
|
|
9193
|
-
const cached = apiClientCache.get(key);
|
|
9194
|
-
if (cached) return cached;
|
|
9195
|
-
const mod = await import("@apple/app-store-server-library");
|
|
9196
|
-
const env12 = creds.environment === "production" ? mod.Environment.PRODUCTION : mod.Environment.SANDBOX;
|
|
9197
|
-
const client = new mod.AppStoreServerAPIClient(creds.privateKeyPem, creds.keyId, creds.issuerId, creds.bundleId, env12);
|
|
9198
|
-
apiClientCache.set(key, client);
|
|
9199
|
-
return client;
|
|
9200
|
-
}
|
|
9201
9402
|
async function getAllSubscriptionStatuses(originalTransactionId, creds) {
|
|
9202
|
-
|
|
9203
|
-
return client.getAllSubscriptionStatuses(originalTransactionId);
|
|
9403
|
+
return nativeGetAllSubscriptionStatuses(originalTransactionId, creds);
|
|
9204
9404
|
}
|
|
9205
|
-
var verifierCache, apiClientCache;
|
|
9206
9405
|
var init_signed_data_verifier = __esm({
|
|
9207
9406
|
"../../blocklets/core/api/src/integrations/app-store/signed-data-verifier.ts"() {
|
|
9208
9407
|
"use strict";
|
|
9209
9408
|
init_logger();
|
|
9210
9409
|
init_env();
|
|
9211
|
-
|
|
9212
|
-
|
|
9213
|
-
|
|
9410
|
+
init_native_jws();
|
|
9411
|
+
init_native_api();
|
|
9412
|
+
}
|
|
9413
|
+
});
|
|
9414
|
+
|
|
9415
|
+
// ../../blocklets/core/api/src/integrations/app-store/native-receipt.ts
|
|
9416
|
+
function toMs(v) {
|
|
9417
|
+
if (v === void 0 || v === null || v === "") return void 0;
|
|
9418
|
+
const n = Number(v);
|
|
9419
|
+
return Number.isNaN(n) ? void 0 : n;
|
|
9420
|
+
}
|
|
9421
|
+
async function postReceipt(host, body) {
|
|
9422
|
+
const response = await fetch(host, {
|
|
9423
|
+
method: "POST",
|
|
9424
|
+
headers: { "Content-Type": "application/json" },
|
|
9425
|
+
body: JSON.stringify(body)
|
|
9426
|
+
});
|
|
9427
|
+
if (!response.ok) {
|
|
9428
|
+
throw new Error(`AppStore verifyReceipt: HTTP ${response.status}`);
|
|
9429
|
+
}
|
|
9430
|
+
return await response.json();
|
|
9431
|
+
}
|
|
9432
|
+
async function verifyAppleReceiptNative({
|
|
9433
|
+
receipt,
|
|
9434
|
+
sharedSecret
|
|
9435
|
+
}) {
|
|
9436
|
+
const body = {
|
|
9437
|
+
"receipt-data": receipt,
|
|
9438
|
+
password: sharedSecret,
|
|
9439
|
+
// Deliberate, result-equivalent: client.ts reduces to the latest-expiry item
|
|
9440
|
+
// anyway, so trimming old transactions here changes nothing downstream.
|
|
9441
|
+
"exclude-old-transactions": true
|
|
9442
|
+
};
|
|
9443
|
+
let data = await postReceipt(PRODUCTION_HOST, body);
|
|
9444
|
+
if (RETRY_SANDBOX_STATUSES.has(data.status)) {
|
|
9445
|
+
data = await postReceipt(SANDBOX_HOST, body);
|
|
9446
|
+
}
|
|
9447
|
+
if (data.status !== 0) {
|
|
9448
|
+
throw new Error(`AppStore verifyReceipt: Apple returned status ${data.status}`);
|
|
9449
|
+
}
|
|
9450
|
+
const rawItems = data.latest_receipt_info ?? data.receipt?.in_app ?? [];
|
|
9451
|
+
const bundleId = data.receipt?.bundle_id;
|
|
9452
|
+
return rawItems.map((item) => ({
|
|
9453
|
+
productId: item.product_id ?? "",
|
|
9454
|
+
transactionId: item.transaction_id ?? "",
|
|
9455
|
+
originalTransactionId: item.original_transaction_id,
|
|
9456
|
+
purchaseDate: toMs(item.purchase_date_ms),
|
|
9457
|
+
expirationDate: toMs(item.expires_date_ms),
|
|
9458
|
+
bundleId,
|
|
9459
|
+
webOrderLineItemId: item.web_order_line_item_id
|
|
9460
|
+
}));
|
|
9461
|
+
}
|
|
9462
|
+
var PRODUCTION_HOST, SANDBOX_HOST, RETRY_SANDBOX_STATUSES;
|
|
9463
|
+
var init_native_receipt = __esm({
|
|
9464
|
+
"../../blocklets/core/api/src/integrations/app-store/native-receipt.ts"() {
|
|
9465
|
+
"use strict";
|
|
9466
|
+
PRODUCTION_HOST = "https://buy.itunes.apple.com/verifyReceipt";
|
|
9467
|
+
SANDBOX_HOST = "https://sandbox.itunes.apple.com/verifyReceipt";
|
|
9468
|
+
RETRY_SANDBOX_STATUSES = /* @__PURE__ */ new Set([21007, 21002]);
|
|
9214
9469
|
}
|
|
9215
9470
|
});
|
|
9216
9471
|
|
|
9217
9472
|
// ../../blocklets/core/api/src/integrations/app-store/client.ts
|
|
9218
|
-
var
|
|
9473
|
+
var AppStoreClient;
|
|
9219
9474
|
var init_client = __esm({
|
|
9220
9475
|
"../../blocklets/core/api/src/integrations/app-store/client.ts"() {
|
|
9221
9476
|
"use strict";
|
|
9222
|
-
import_node_apple_receipt_verify = require("node-apple-receipt-verify");
|
|
9223
9477
|
init_env();
|
|
9224
9478
|
init_logger();
|
|
9225
9479
|
init_signed_data_verifier();
|
|
9480
|
+
init_native_receipt();
|
|
9226
9481
|
AppStoreClient = class _AppStoreClient {
|
|
9227
9482
|
constructor(settings, environment) {
|
|
9228
9483
|
this.bundleId = settings.bundle_id;
|
|
@@ -9327,9 +9582,9 @@ var init_client = __esm({
|
|
|
9327
9582
|
/**
|
|
9328
9583
|
* Verify a StoreKit 1 (legacy) base64 receipt via Apple's verifyReceipt endpoint.
|
|
9329
9584
|
*
|
|
9330
|
-
* Calls `
|
|
9585
|
+
* Calls the native `verifyAppleReceiptNative` which POSTs to
|
|
9331
9586
|
* https://buy.itunes.apple.com/verifyReceipt (production)
|
|
9332
|
-
* https://sandbox.itunes.apple.com/verifyReceipt (sandbox, auto fallback)
|
|
9587
|
+
* https://sandbox.itunes.apple.com/verifyReceipt (sandbox, auto fallback on 21007/21002)
|
|
9333
9588
|
*
|
|
9334
9589
|
* Returns a payload shaped like a StoreKit 2 transaction so downstream code
|
|
9335
9590
|
* (ingestVerifiedAppStorePurchase) can stay agnostic. Note: legacy receipts
|
|
@@ -9343,12 +9598,7 @@ var init_client = __esm({
|
|
|
9343
9598
|
if (!this.sharedSecret) {
|
|
9344
9599
|
throw new Error("AppStoreClient: shared_secret is required for legacy receipt verification");
|
|
9345
9600
|
}
|
|
9346
|
-
(
|
|
9347
|
-
secret: this.sharedSecret,
|
|
9348
|
-
verbose: false,
|
|
9349
|
-
environment: ["production", "sandbox"]
|
|
9350
|
-
});
|
|
9351
|
-
const items = await (0, import_node_apple_receipt_verify.validate)({ receipt });
|
|
9601
|
+
const items = await verifyAppleReceiptNative({ receipt, sharedSecret: this.sharedSecret });
|
|
9352
9602
|
const filtered = options.expectedProductIds ? items.filter((i) => options.expectedProductIds.includes(i.productId)) : items;
|
|
9353
9603
|
if (!filtered.length) {
|
|
9354
9604
|
throw new Error("AppStoreClient: verifyReceipt returned no matching purchases");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcblock/payment-service",
|
|
3
|
-
"version": "1.29.
|
|
3
|
+
"version": "1.29.7",
|
|
4
4
|
"description": "Embedded payment service factory (W2) — side-effect-free core for arc / blocklet server / standalone worker hosts",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -37,7 +37,6 @@
|
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@abtnode/cron": "^1.17.13-beta-20260613-094425-b81920c8",
|
|
40
|
-
"@apple/app-store-server-library": "^3.1.0",
|
|
41
40
|
"@arcblock/did": "^1.30.24",
|
|
42
41
|
"@arcblock/did-connect-storage-nedb": "^1.8.0",
|
|
43
42
|
"@arcblock/did-util": "^1.30.24",
|
|
@@ -45,7 +44,7 @@
|
|
|
45
44
|
"@blocklet/constant": "^1.17.13-beta-20260613-094425-b81920c8",
|
|
46
45
|
"@blocklet/error": "^0.3.5",
|
|
47
46
|
"@blocklet/logger": "^1.17.13-beta-20260613-094425-b81920c8",
|
|
48
|
-
"@blocklet/payment-vendor": "1.29.
|
|
47
|
+
"@blocklet/payment-vendor": "1.29.7",
|
|
49
48
|
"@blocklet/sdk": "^1.17.13-beta-20260613-094425-b81920c8",
|
|
50
49
|
"@blocklet/xss": "^0.3.16",
|
|
51
50
|
"@hono/node-server": "^2.0.4",
|
|
@@ -70,7 +69,6 @@
|
|
|
70
69
|
"json-stable-stringify": "^1.3.0",
|
|
71
70
|
"lodash": "^4.17.21",
|
|
72
71
|
"nanoid": "^3.3.11",
|
|
73
|
-
"node-apple-receipt-verify": "^1.15.0",
|
|
74
72
|
"p-all": "3.0.0",
|
|
75
73
|
"p-wait-for": "^3.2.0",
|
|
76
74
|
"pretty-ms-i18n": "^1.0.3",
|
|
@@ -92,5 +90,5 @@
|
|
|
92
90
|
"ts-jest": "^29.1.2",
|
|
93
91
|
"typescript": "^5.4.3"
|
|
94
92
|
},
|
|
95
|
-
"gitHead": "
|
|
93
|
+
"gitHead": "e1999aecfa9ce64bfd56da14bf47b255a19ef394"
|
|
96
94
|
}
|