moltspay 1.6.0 → 2.0.0
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/README.md +1 -0
- package/dist/cdp/index.js.map +1 -1
- package/dist/cdp/index.mjs.map +1 -1
- package/dist/{cdp-DeohBe1o.d.ts → cdp-B5PhDUTC.d.ts} +1 -1
- package/dist/{cdp-p_eHuQpb.d.mts → cdp-D-5Hg3y_.d.mts} +1 -1
- package/dist/chains/index.d.mts +37 -1
- package/dist/chains/index.d.ts +37 -1
- package/dist/chains/index.js +22 -0
- package/dist/chains/index.js.map +1 -1
- package/dist/chains/index.mjs +19 -0
- package/dist/chains/index.mjs.map +1 -1
- package/dist/cli/index.js +1466 -61
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +1466 -61
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/index.d.mts +41 -0
- package/dist/client/index.d.ts +41 -0
- package/dist/client/index.js +824 -10
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +824 -10
- package/dist/client/index.mjs.map +1 -1
- package/dist/client/web/index.d.mts +17 -1
- package/dist/client/web/index.mjs +11 -0
- package/dist/client/web/index.mjs.map +1 -1
- package/dist/facilitators/index.d.mts +161 -4
- package/dist/facilitators/index.d.ts +161 -4
- package/dist/facilitators/index.js +370 -0
- package/dist/facilitators/index.js.map +1 -1
- package/dist/facilitators/index.mjs +365 -0
- package/dist/facilitators/index.mjs.map +1 -1
- package/dist/index.d.mts +77 -2
- package/dist/index.d.ts +77 -2
- package/dist/index.js +1412 -31
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1406 -31
- package/dist/index.mjs.map +1 -1
- package/dist/mcp/index.js +828 -14
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/index.mjs +828 -14
- package/dist/mcp/index.mjs.map +1 -1
- package/dist/{registry-OsEO2dOu.d.mts → registry-DIo0WNoO.d.mts} +8 -1
- package/dist/{registry-OsEO2dOu.d.ts → registry-DIo0WNoO.d.ts} +8 -1
- package/dist/server/index.d.mts +95 -2
- package/dist/server/index.d.ts +95 -2
- package/dist/server/index.js +554 -14
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +554 -14
- package/dist/server/index.mjs.map +1 -1
- package/dist/verify/index.js.map +1 -1
- package/dist/verify/index.mjs.map +1 -1
- package/dist/wallet/index.js.map +1 -1
- package/dist/wallet/index.mjs.map +1 -1
- package/package.json +7 -1
- package/schemas/moltspay.services.schema.json +100 -6
- package/scripts/postinstall.js +91 -0
|
@@ -30,6 +30,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/facilitators/index.ts
|
|
31
31
|
var facilitators_exports = {};
|
|
32
32
|
__export(facilitators_exports, {
|
|
33
|
+
ALIPAY_GATEWAY_PROD: () => ALIPAY_GATEWAY_PROD,
|
|
34
|
+
ALIPAY_GATEWAY_SANDBOX: () => ALIPAY_GATEWAY_SANDBOX,
|
|
35
|
+
ALIPAY_NETWORK: () => ALIPAY_NETWORK,
|
|
36
|
+
ALIPAY_SCHEME: () => ALIPAY_SCHEME,
|
|
37
|
+
AlipayFacilitator: () => AlipayFacilitator,
|
|
33
38
|
BNBFacilitator: () => BNBFacilitator,
|
|
34
39
|
BaseFacilitator: () => BaseFacilitator,
|
|
35
40
|
CDPFacilitator: () => CDPFacilitator,
|
|
@@ -1253,6 +1258,365 @@ async function createSolanaPaymentTransaction(senderPubkey, recipientPubkey, amo
|
|
|
1253
1258
|
return transaction;
|
|
1254
1259
|
}
|
|
1255
1260
|
|
|
1261
|
+
// src/facilitators/alipay.ts
|
|
1262
|
+
var import_node_crypto2 = __toESM(require("crypto"));
|
|
1263
|
+
|
|
1264
|
+
// src/facilitators/alipay/rsa2.ts
|
|
1265
|
+
var import_node_crypto = __toESM(require("crypto"));
|
|
1266
|
+
function rsa2Sign(data, privateKeyPem) {
|
|
1267
|
+
const signer = import_node_crypto.default.createSign("RSA-SHA256");
|
|
1268
|
+
signer.update(data, "utf-8");
|
|
1269
|
+
signer.end();
|
|
1270
|
+
return signer.sign(privateKeyPem, "base64");
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
// src/facilitators/alipay/encoding.ts
|
|
1274
|
+
function base64url(input) {
|
|
1275
|
+
return Buffer.from(input, "utf-8").toString("base64url");
|
|
1276
|
+
}
|
|
1277
|
+
function decodeBase64UrlWithPadFix(input) {
|
|
1278
|
+
const normalized = input.replace(/-/g, "+").replace(/_/g, "/");
|
|
1279
|
+
const padded = normalized + "=".repeat((4 - normalized.length % 4) % 4);
|
|
1280
|
+
return Buffer.from(padded, "base64").toString("utf-8");
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
// src/facilitators/alipay/openapi.ts
|
|
1284
|
+
function formatAlipayTimestamp(d = /* @__PURE__ */ new Date()) {
|
|
1285
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
1286
|
+
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
|
|
1287
|
+
}
|
|
1288
|
+
function buildSigningString(params) {
|
|
1289
|
+
return Object.keys(params).sort().map((k) => `${k}=${params[k]}`).join("&");
|
|
1290
|
+
}
|
|
1291
|
+
function responseWrapperKey(method) {
|
|
1292
|
+
return `${method.replace(/\./g, "_")}_response`;
|
|
1293
|
+
}
|
|
1294
|
+
async function alipayOpenApiCall(method, bizContent, config) {
|
|
1295
|
+
const publicParams = {
|
|
1296
|
+
app_id: config.app_id,
|
|
1297
|
+
method,
|
|
1298
|
+
format: "JSON",
|
|
1299
|
+
charset: "utf-8",
|
|
1300
|
+
sign_type: config.sign_type ?? "RSA2",
|
|
1301
|
+
timestamp: formatAlipayTimestamp(),
|
|
1302
|
+
version: "1.0",
|
|
1303
|
+
biz_content: JSON.stringify(bizContent)
|
|
1304
|
+
};
|
|
1305
|
+
const signingString = buildSigningString(publicParams);
|
|
1306
|
+
const sign = rsa2Sign(signingString, config.private_key_pem);
|
|
1307
|
+
const body = new URLSearchParams({ ...publicParams, sign }).toString();
|
|
1308
|
+
const response = await fetch(config.gateway_url, {
|
|
1309
|
+
method: "POST",
|
|
1310
|
+
headers: {
|
|
1311
|
+
"Content-Type": "application/x-www-form-urlencoded;charset=utf-8"
|
|
1312
|
+
},
|
|
1313
|
+
body
|
|
1314
|
+
});
|
|
1315
|
+
if (!response.ok) {
|
|
1316
|
+
const text = await response.text().catch(() => "<unreadable>");
|
|
1317
|
+
throw new Error(
|
|
1318
|
+
`Alipay Open API HTTP ${response.status} for ${method}: ${text.slice(0, 500)}`
|
|
1319
|
+
);
|
|
1320
|
+
}
|
|
1321
|
+
const json = await response.json();
|
|
1322
|
+
const wrapperKey = responseWrapperKey(method);
|
|
1323
|
+
const business = json[wrapperKey];
|
|
1324
|
+
if (business === void 0 || business === null || typeof business !== "object") {
|
|
1325
|
+
throw new Error(
|
|
1326
|
+
`Alipay Open API response missing "${wrapperKey}" wrapper for ${method}: ${JSON.stringify(json).slice(0, 500)}`
|
|
1327
|
+
);
|
|
1328
|
+
}
|
|
1329
|
+
return business;
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
// src/facilitators/alipay.ts
|
|
1333
|
+
var ALIPAY_NETWORK = "alipay";
|
|
1334
|
+
var ALIPAY_SCHEME = "alipay-aipay";
|
|
1335
|
+
var ALIPAY_GATEWAY_PROD = "https://openapi.alipay.com/gateway.do";
|
|
1336
|
+
var ALIPAY_GATEWAY_SANDBOX = "https://openapi.alipaydev.com/gateway.do";
|
|
1337
|
+
var ALIPAY_AMOUNT_REGEX = /^\d+(\.\d{1,2})?$/;
|
|
1338
|
+
var ALIPAY_PAY_BEFORE_MS = 30 * 60 * 1e3;
|
|
1339
|
+
var ALIPAY_SIGNING_FIELDS = [
|
|
1340
|
+
"amount",
|
|
1341
|
+
"currency",
|
|
1342
|
+
"goods_name",
|
|
1343
|
+
"out_trade_no",
|
|
1344
|
+
"pay_before",
|
|
1345
|
+
"resource_id",
|
|
1346
|
+
"seller_id",
|
|
1347
|
+
"service_id"
|
|
1348
|
+
];
|
|
1349
|
+
var AlipayFacilitator = class extends BaseFacilitator {
|
|
1350
|
+
name = "alipay";
|
|
1351
|
+
displayName = "Alipay AI \u6536";
|
|
1352
|
+
supportedNetworks = [ALIPAY_NETWORK];
|
|
1353
|
+
config;
|
|
1354
|
+
constructor(config) {
|
|
1355
|
+
super();
|
|
1356
|
+
this.config = {
|
|
1357
|
+
gateway_url: ALIPAY_GATEWAY_PROD,
|
|
1358
|
+
sign_type: "RSA2",
|
|
1359
|
+
...config
|
|
1360
|
+
};
|
|
1361
|
+
}
|
|
1362
|
+
/**
|
|
1363
|
+
* Build the 402 challenge for a service: signs the 8-field payload with
|
|
1364
|
+
* RSA2, packages the nested `{protocol, method}` JSON as Base64URL for
|
|
1365
|
+
* `Payment-Needed`, and emits the parallel x402 `accepts[]` entry.
|
|
1366
|
+
*/
|
|
1367
|
+
async createPaymentRequirements(opts) {
|
|
1368
|
+
if (!ALIPAY_AMOUNT_REGEX.test(opts.priceCny)) {
|
|
1369
|
+
throw new Error(
|
|
1370
|
+
`AlipayFacilitator.createPaymentRequirements: priceCny "${opts.priceCny}" does not match /^\\d+(\\.\\d{1,2})?$/ (unit is \u5143, not \u5206; e.g. "1.00" not "100")`
|
|
1371
|
+
);
|
|
1372
|
+
}
|
|
1373
|
+
const now = /* @__PURE__ */ new Date();
|
|
1374
|
+
const outTradeNo = opts.outTradeNo ?? generateOutTradeNo();
|
|
1375
|
+
const payBefore = formatPayBefore(now);
|
|
1376
|
+
const signedFields = {
|
|
1377
|
+
amount: opts.priceCny,
|
|
1378
|
+
currency: "CNY",
|
|
1379
|
+
goods_name: opts.goodsName,
|
|
1380
|
+
out_trade_no: outTradeNo,
|
|
1381
|
+
pay_before: payBefore,
|
|
1382
|
+
resource_id: opts.resourceId,
|
|
1383
|
+
seller_id: this.config.seller_id,
|
|
1384
|
+
service_id: opts.serviceId
|
|
1385
|
+
};
|
|
1386
|
+
const signingString = ALIPAY_SIGNING_FIELDS.map((k) => `${k}=${signedFields[k]}`).join("&");
|
|
1387
|
+
const seller_signature = rsa2Sign(signingString, this.config.private_key_pem);
|
|
1388
|
+
const challenge = {
|
|
1389
|
+
protocol: {
|
|
1390
|
+
out_trade_no: outTradeNo,
|
|
1391
|
+
amount: signedFields.amount,
|
|
1392
|
+
currency: signedFields.currency,
|
|
1393
|
+
resource_id: signedFields.resource_id,
|
|
1394
|
+
pay_before: payBefore,
|
|
1395
|
+
seller_signature,
|
|
1396
|
+
seller_sign_type: this.config.sign_type ?? "RSA2",
|
|
1397
|
+
seller_unique_id: this.config.seller_id
|
|
1398
|
+
},
|
|
1399
|
+
method: {
|
|
1400
|
+
seller_name: this.config.seller_name,
|
|
1401
|
+
seller_id: this.config.seller_id,
|
|
1402
|
+
seller_app_id: this.config.app_id,
|
|
1403
|
+
goods_name: signedFields.goods_name,
|
|
1404
|
+
seller_unique_id_key: "seller_id",
|
|
1405
|
+
service_id: signedFields.service_id
|
|
1406
|
+
}
|
|
1407
|
+
};
|
|
1408
|
+
const paymentNeededHeader = base64url(JSON.stringify(challenge));
|
|
1409
|
+
const x402Accepts = {
|
|
1410
|
+
scheme: ALIPAY_SCHEME,
|
|
1411
|
+
network: ALIPAY_NETWORK,
|
|
1412
|
+
asset: "CNY",
|
|
1413
|
+
amount: opts.priceCny,
|
|
1414
|
+
payTo: this.config.seller_id,
|
|
1415
|
+
maxTimeoutSeconds: ALIPAY_PAY_BEFORE_MS / 1e3,
|
|
1416
|
+
extra: {
|
|
1417
|
+
payment_needed_header: paymentNeededHeader,
|
|
1418
|
+
out_trade_no: outTradeNo,
|
|
1419
|
+
pay_before: payBefore,
|
|
1420
|
+
service_id: signedFields.service_id
|
|
1421
|
+
}
|
|
1422
|
+
};
|
|
1423
|
+
return { x402Accepts, paymentNeededHeader };
|
|
1424
|
+
}
|
|
1425
|
+
/**
|
|
1426
|
+
* Verify a `Payment-Proof` by calling
|
|
1427
|
+
* `alipay.aipay.agent.payment.verify` against the Alipay Open API.
|
|
1428
|
+
*
|
|
1429
|
+
* The proof is conveyed via `paymentPayload.payload`, which may be:
|
|
1430
|
+
* - a raw Base64URL string (the `Payment-Proof` header value), or
|
|
1431
|
+
* - an object `{ paymentProof: string }` / `{ proofHeader: string }`.
|
|
1432
|
+
*
|
|
1433
|
+
* All failure modes (malformed payload, network errors, Alipay
|
|
1434
|
+
* `code != 10000`) return `{ valid: false, error }`. No exception
|
|
1435
|
+
* escapes, regardless of client-supplied input.
|
|
1436
|
+
*/
|
|
1437
|
+
async verify(paymentPayload, _requirements) {
|
|
1438
|
+
try {
|
|
1439
|
+
const proofHeader = extractProofHeader(paymentPayload.payload);
|
|
1440
|
+
const decoded = decodeProof(proofHeader);
|
|
1441
|
+
const response = await alipayOpenApiCall(
|
|
1442
|
+
"alipay.aipay.agent.payment.verify",
|
|
1443
|
+
{
|
|
1444
|
+
payment_proof: decoded.protocol.payment_proof,
|
|
1445
|
+
trade_no: decoded.protocol.trade_no,
|
|
1446
|
+
client_session: decoded.method.client_session
|
|
1447
|
+
},
|
|
1448
|
+
this.getOpenApiConfig()
|
|
1449
|
+
);
|
|
1450
|
+
if (response.code !== "10000") {
|
|
1451
|
+
return {
|
|
1452
|
+
valid: false,
|
|
1453
|
+
error: `alipay verify ${response.code}: ${response.sub_msg ?? response.msg ?? "unknown"}`,
|
|
1454
|
+
details: {
|
|
1455
|
+
code: response.code,
|
|
1456
|
+
sub_code: response.sub_code,
|
|
1457
|
+
sub_msg: response.sub_msg
|
|
1458
|
+
}
|
|
1459
|
+
};
|
|
1460
|
+
}
|
|
1461
|
+
return {
|
|
1462
|
+
valid: true,
|
|
1463
|
+
details: {
|
|
1464
|
+
trade_no: response.trade_no ?? decoded.protocol.trade_no,
|
|
1465
|
+
amount: response.amount,
|
|
1466
|
+
out_trade_no: response.out_trade_no,
|
|
1467
|
+
resource_id: response.resource_id,
|
|
1468
|
+
active: response.active
|
|
1469
|
+
}
|
|
1470
|
+
};
|
|
1471
|
+
} catch (e) {
|
|
1472
|
+
return {
|
|
1473
|
+
valid: false,
|
|
1474
|
+
error: e instanceof Error ? e.message : String(e)
|
|
1475
|
+
};
|
|
1476
|
+
}
|
|
1477
|
+
}
|
|
1478
|
+
/**
|
|
1479
|
+
* Settle by calling `alipay.aipay.agent.fulfillment.confirm` after the
|
|
1480
|
+
* service resource has been returned to the buyer.
|
|
1481
|
+
*
|
|
1482
|
+
* Per the design (see ALIPAY-INTEGRATION-DESIGN.md §5.1, risk row
|
|
1483
|
+
* "履约确认失败"), this is **fire-and-forget**: the caller (registry /
|
|
1484
|
+
* server) is expected to log fulfillment failures but NOT roll back
|
|
1485
|
+
* the already-delivered resource.
|
|
1486
|
+
*
|
|
1487
|
+
* Re-decodes `paymentPayload.payload` to extract `trade_no` (verify
|
|
1488
|
+
* does the same; the redundant Base64URL decode is negligible).
|
|
1489
|
+
*/
|
|
1490
|
+
async settle(paymentPayload, _requirements) {
|
|
1491
|
+
try {
|
|
1492
|
+
const proofHeader = extractProofHeader(paymentPayload.payload);
|
|
1493
|
+
const decoded = decodeProof(proofHeader);
|
|
1494
|
+
const tradeNo = decoded.protocol.trade_no;
|
|
1495
|
+
const response = await alipayOpenApiCall(
|
|
1496
|
+
"alipay.aipay.agent.fulfillment.confirm",
|
|
1497
|
+
{ trade_no: tradeNo },
|
|
1498
|
+
this.getOpenApiConfig()
|
|
1499
|
+
);
|
|
1500
|
+
if (response.code !== "10000") {
|
|
1501
|
+
return {
|
|
1502
|
+
success: false,
|
|
1503
|
+
transaction: tradeNo,
|
|
1504
|
+
error: `alipay fulfillment ${response.code}: ${response.sub_msg ?? response.msg ?? "unknown"}`,
|
|
1505
|
+
status: "fulfillment_failed"
|
|
1506
|
+
};
|
|
1507
|
+
}
|
|
1508
|
+
return {
|
|
1509
|
+
success: true,
|
|
1510
|
+
transaction: tradeNo,
|
|
1511
|
+
status: "fulfilled"
|
|
1512
|
+
};
|
|
1513
|
+
} catch (e) {
|
|
1514
|
+
return {
|
|
1515
|
+
success: false,
|
|
1516
|
+
error: e instanceof Error ? e.message : String(e)
|
|
1517
|
+
};
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
/**
|
|
1521
|
+
* Validate that the configured RSA keys parse and that the Open API
|
|
1522
|
+
* gateway is reachable. Does NOT make a real business API call (would
|
|
1523
|
+
* burn quota and could appear as a legitimate verify attempt in logs).
|
|
1524
|
+
*/
|
|
1525
|
+
async healthCheck() {
|
|
1526
|
+
const start = Date.now();
|
|
1527
|
+
try {
|
|
1528
|
+
import_node_crypto2.default.createPrivateKey(this.config.private_key_pem);
|
|
1529
|
+
} catch (e) {
|
|
1530
|
+
return {
|
|
1531
|
+
healthy: false,
|
|
1532
|
+
error: `merchant private_key_pem parse failed: ${e instanceof Error ? e.message : String(e)}`
|
|
1533
|
+
};
|
|
1534
|
+
}
|
|
1535
|
+
try {
|
|
1536
|
+
import_node_crypto2.default.createPublicKey(this.config.alipay_public_key_pem);
|
|
1537
|
+
} catch (e) {
|
|
1538
|
+
return {
|
|
1539
|
+
healthy: false,
|
|
1540
|
+
error: `alipay_public_key_pem parse failed: ${e instanceof Error ? e.message : String(e)}`
|
|
1541
|
+
};
|
|
1542
|
+
}
|
|
1543
|
+
const gatewayUrl = this.config.gateway_url ?? ALIPAY_GATEWAY_PROD;
|
|
1544
|
+
const controller = new AbortController();
|
|
1545
|
+
const timeout = setTimeout(() => controller.abort(), 5e3);
|
|
1546
|
+
const response = await fetch(gatewayUrl, {
|
|
1547
|
+
method: "HEAD",
|
|
1548
|
+
signal: controller.signal
|
|
1549
|
+
}).catch(() => null);
|
|
1550
|
+
clearTimeout(timeout);
|
|
1551
|
+
const latencyMs = Date.now() - start;
|
|
1552
|
+
if (!response) {
|
|
1553
|
+
return { healthy: false, error: `gateway unreachable: ${gatewayUrl}`, latencyMs };
|
|
1554
|
+
}
|
|
1555
|
+
return { healthy: true, latencyMs };
|
|
1556
|
+
}
|
|
1557
|
+
/** Bundle the facilitator config into the shape openapi.ts wants. */
|
|
1558
|
+
getOpenApiConfig() {
|
|
1559
|
+
return {
|
|
1560
|
+
gateway_url: this.config.gateway_url ?? ALIPAY_GATEWAY_PROD,
|
|
1561
|
+
app_id: this.config.app_id,
|
|
1562
|
+
private_key_pem: this.config.private_key_pem,
|
|
1563
|
+
alipay_public_key_pem: this.config.alipay_public_key_pem,
|
|
1564
|
+
sign_type: this.config.sign_type
|
|
1565
|
+
};
|
|
1566
|
+
}
|
|
1567
|
+
};
|
|
1568
|
+
function generateOutTradeNo() {
|
|
1569
|
+
return "VID" + import_node_crypto2.default.randomBytes(22).toString("base64url").slice(0, 29);
|
|
1570
|
+
}
|
|
1571
|
+
function formatPayBefore(now) {
|
|
1572
|
+
const expiry = new Date(now.getTime() + ALIPAY_PAY_BEFORE_MS);
|
|
1573
|
+
return expiry.toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
1574
|
+
}
|
|
1575
|
+
function extractProofHeader(payload) {
|
|
1576
|
+
if (typeof payload === "string") {
|
|
1577
|
+
if (payload.length === 0) {
|
|
1578
|
+
throw new Error("alipay Payment-Proof is empty");
|
|
1579
|
+
}
|
|
1580
|
+
return payload;
|
|
1581
|
+
}
|
|
1582
|
+
if (payload !== null && typeof payload === "object") {
|
|
1583
|
+
const obj = payload;
|
|
1584
|
+
const candidate = obj.paymentProof ?? obj.proofHeader;
|
|
1585
|
+
if (typeof candidate === "string" && candidate.length > 0) {
|
|
1586
|
+
return candidate;
|
|
1587
|
+
}
|
|
1588
|
+
}
|
|
1589
|
+
throw new Error(
|
|
1590
|
+
"alipay payment payload must be a Base64URL string or {paymentProof: string} / {proofHeader: string}"
|
|
1591
|
+
);
|
|
1592
|
+
}
|
|
1593
|
+
function decodeProof(proofHeader) {
|
|
1594
|
+
let parsed;
|
|
1595
|
+
try {
|
|
1596
|
+
parsed = JSON.parse(decodeBase64UrlWithPadFix(proofHeader));
|
|
1597
|
+
} catch (e) {
|
|
1598
|
+
throw new Error(
|
|
1599
|
+
`failed to decode Payment-Proof: ${e instanceof Error ? e.message : String(e)}`
|
|
1600
|
+
);
|
|
1601
|
+
}
|
|
1602
|
+
if (parsed === null || typeof parsed !== "object") {
|
|
1603
|
+
throw new Error("decoded Payment-Proof is not an object");
|
|
1604
|
+
}
|
|
1605
|
+
const obj = parsed;
|
|
1606
|
+
const protocol = obj.protocol;
|
|
1607
|
+
const method = obj.method;
|
|
1608
|
+
if (!protocol || typeof protocol.payment_proof !== "string") {
|
|
1609
|
+
throw new Error("decoded Payment-Proof missing protocol.payment_proof");
|
|
1610
|
+
}
|
|
1611
|
+
if (typeof protocol.trade_no !== "string") {
|
|
1612
|
+
throw new Error("decoded Payment-Proof missing protocol.trade_no");
|
|
1613
|
+
}
|
|
1614
|
+
if (!method || typeof method.client_session !== "string") {
|
|
1615
|
+
throw new Error("decoded Payment-Proof missing method.client_session");
|
|
1616
|
+
}
|
|
1617
|
+
return parsed;
|
|
1618
|
+
}
|
|
1619
|
+
|
|
1256
1620
|
// src/facilitators/registry.ts
|
|
1257
1621
|
var import_web33 = require("@solana/web3.js");
|
|
1258
1622
|
var import_bs58 = __toESM(require("bs58"));
|
|
@@ -1277,6 +1641,7 @@ var FacilitatorRegistry = class {
|
|
|
1277
1641
|
}
|
|
1278
1642
|
return new SolanaFacilitator({ feePayerKeypair });
|
|
1279
1643
|
});
|
|
1644
|
+
this.registerFactory("alipay", (config) => new AlipayFacilitator(config));
|
|
1280
1645
|
this.selection = selection || { primary: "cdp", fallback: ["tempo", "bnb", "solana"], strategy: "failover" };
|
|
1281
1646
|
}
|
|
1282
1647
|
/**
|
|
@@ -1504,6 +1869,11 @@ function createRegistry(selection) {
|
|
|
1504
1869
|
}
|
|
1505
1870
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1506
1871
|
0 && (module.exports = {
|
|
1872
|
+
ALIPAY_GATEWAY_PROD,
|
|
1873
|
+
ALIPAY_GATEWAY_SANDBOX,
|
|
1874
|
+
ALIPAY_NETWORK,
|
|
1875
|
+
ALIPAY_SCHEME,
|
|
1876
|
+
AlipayFacilitator,
|
|
1507
1877
|
BNBFacilitator,
|
|
1508
1878
|
BaseFacilitator,
|
|
1509
1879
|
CDPFacilitator,
|