@crediblemark/buayar 0.5.1 → 0.6.1
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/index.d.mts +137 -1
- package/dist/index.d.ts +137 -1
- package/dist/index.js +514 -25
- package/dist/index.mjs +488 -8
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -78,6 +78,7 @@ __export(index_exports, {
|
|
|
78
78
|
PrismalinkProvider: () => PrismalinkProvider,
|
|
79
79
|
RazorpayClient: () => RazorpayClient,
|
|
80
80
|
RazorpayProvider: () => RazorpayProvider,
|
|
81
|
+
SnapClient: () => SnapClient,
|
|
81
82
|
SquareClient: () => SquareClient,
|
|
82
83
|
SquareProvider: () => SquareProvider,
|
|
83
84
|
StripeClient: () => StripeClient,
|
|
@@ -101,6 +102,8 @@ __export(index_exports, {
|
|
|
101
102
|
generateNicepayToken: () => generateNicepayToken,
|
|
102
103
|
generateOyHeaders: () => generateOyHeaders,
|
|
103
104
|
generatePrismalinkSignature: () => generatePrismalinkSignature,
|
|
105
|
+
generateSnapAsymmetricSignature: () => generateSnapAsymmetricSignature,
|
|
106
|
+
generateSnapSymmetricSignature: () => generateSnapSymmetricSignature,
|
|
104
107
|
getDuitkuInquirySignatures: () => getDuitkuInquirySignatures,
|
|
105
108
|
getDuitkuPaymentMethodsSignature: () => getDuitkuPaymentMethodsSignature,
|
|
106
109
|
getDuitkuStatusSignatures: () => getDuitkuStatusSignatures,
|
|
@@ -108,6 +111,7 @@ __export(index_exports, {
|
|
|
108
111
|
getXenditAuthHeader: () => getXenditAuthHeader,
|
|
109
112
|
hmacSha256: () => hmacSha256,
|
|
110
113
|
md5: () => md5,
|
|
114
|
+
minifyJson: () => minifyJson,
|
|
111
115
|
parseCoreChargeResponse: () => parseCoreChargeResponse,
|
|
112
116
|
paymentManager: () => paymentManager,
|
|
113
117
|
resolveConfigFromEnv: () => resolveConfigFromEnv,
|
|
@@ -115,7 +119,11 @@ __export(index_exports, {
|
|
|
115
119
|
serializePaypalParams: () => serializePaypalParams,
|
|
116
120
|
serializeStripeParams: () => serializeStripeParams,
|
|
117
121
|
sha256: () => sha256,
|
|
122
|
+
sha256Hex: () => sha256Hex,
|
|
118
123
|
sha512: () => sha512,
|
|
124
|
+
snapExternalId: () => snapExternalId,
|
|
125
|
+
snapTimestamp: () => snapTimestamp,
|
|
126
|
+
snapUtcTimestamp: () => snapUtcTimestamp,
|
|
119
127
|
toCanonicalPaymentMethod: () => toCanonicalPaymentMethod,
|
|
120
128
|
toDokuPaymentMethod: () => toDokuPaymentMethod,
|
|
121
129
|
toDuitkuPaymentMethod: () => toDuitkuPaymentMethod,
|
|
@@ -141,6 +149,7 @@ __export(index_exports, {
|
|
|
141
149
|
verifyPayuWebhook: () => verifyPayuWebhook,
|
|
142
150
|
verifyPrismalinkSignature: () => verifyPrismalinkSignature,
|
|
143
151
|
verifyRazorpayWebhook: () => verifyRazorpayWebhook,
|
|
152
|
+
verifySnapWebhookSignature: () => verifySnapWebhookSignature,
|
|
144
153
|
verifySquareWebhook: () => verifySquareWebhook,
|
|
145
154
|
verifyStripeWebhook: () => verifyStripeWebhook,
|
|
146
155
|
verifyTwoCheckoutWebhook: () => verifyTwoCheckoutWebhook,
|
|
@@ -2563,12 +2572,221 @@ Digest:${digest}`;
|
|
|
2563
2572
|
return safeCompare(incomingSignature, expectedSignature);
|
|
2564
2573
|
}
|
|
2565
2574
|
|
|
2575
|
+
// src/providers/doku/snap.ts
|
|
2576
|
+
var import_crypto8 = __toESM(require("crypto"));
|
|
2577
|
+
function snapTimestamp(date = /* @__PURE__ */ new Date()) {
|
|
2578
|
+
const wib = new Date(date.getTime() + 7 * 60 * 60 * 1e3);
|
|
2579
|
+
return wib.toISOString().slice(0, 19) + "+07:00";
|
|
2580
|
+
}
|
|
2581
|
+
function snapUtcTimestamp(date = /* @__PURE__ */ new Date()) {
|
|
2582
|
+
return date.toISOString().slice(0, 19) + "Z";
|
|
2583
|
+
}
|
|
2584
|
+
function minifyJson(obj) {
|
|
2585
|
+
return JSON.stringify(obj);
|
|
2586
|
+
}
|
|
2587
|
+
function sha256Hex(body) {
|
|
2588
|
+
const raw = typeof body === "string" ? body : minifyJson(body);
|
|
2589
|
+
return import_crypto8.default.createHash("sha256").update(raw).digest("hex").toLowerCase();
|
|
2590
|
+
}
|
|
2591
|
+
function generateSnapSymmetricSignature(clientSecret, method, endpointUrl, accessToken, body, timestamp) {
|
|
2592
|
+
const hash = sha256Hex(body);
|
|
2593
|
+
const stringToSign = `${method}:${endpointUrl}:${accessToken}:${hash}:${timestamp}`;
|
|
2594
|
+
return import_crypto8.default.createHmac("sha512", clientSecret).update(stringToSign).digest("base64");
|
|
2595
|
+
}
|
|
2596
|
+
function generateSnapAsymmetricSignature(privateKey, clientId, timestamp) {
|
|
2597
|
+
const stringToSign = `${clientId}|${timestamp}`;
|
|
2598
|
+
const key = import_crypto8.default.createPrivateKey(normalizePem(privateKey));
|
|
2599
|
+
return import_crypto8.default.sign("RSA-SHA256", Buffer.from(stringToSign, "utf8"), key).toString("base64");
|
|
2600
|
+
}
|
|
2601
|
+
function normalizePem(key) {
|
|
2602
|
+
const trimmed = key.trim();
|
|
2603
|
+
if (trimmed.includes("-----BEGIN")) {
|
|
2604
|
+
return trimmed;
|
|
2605
|
+
}
|
|
2606
|
+
return [
|
|
2607
|
+
"-----BEGIN PRIVATE KEY-----",
|
|
2608
|
+
trimmed.replace(/\s+/g, "").match(/.{1,64}/g)?.join("\n") || trimmed,
|
|
2609
|
+
"-----END PRIVATE KEY-----"
|
|
2610
|
+
].join("\n");
|
|
2611
|
+
}
|
|
2612
|
+
function snapExternalId(prefix = "") {
|
|
2613
|
+
return `${prefix}${Date.now()}${Math.floor(Math.random() * 1e3)}`;
|
|
2614
|
+
}
|
|
2615
|
+
function verifySnapWebhookSignature(headers, body, clientSecret, endpointUrl = "/api/payment/webhook") {
|
|
2616
|
+
if (!clientSecret) return false;
|
|
2617
|
+
const incoming = headers["x-signature"] || headers["X-SIGNATURE"] || headers["signature"] || headers["Signature"] || "";
|
|
2618
|
+
if (!incoming) return false;
|
|
2619
|
+
const timestamp = headers["x-timestamp"] || headers["X-TIMESTAMP"] || headers["timestamp"] || headers["Timestamp"] || snapTimestamp();
|
|
2620
|
+
const computed = generateSnapSymmetricSignature(
|
|
2621
|
+
clientSecret,
|
|
2622
|
+
"POST",
|
|
2623
|
+
endpointUrl,
|
|
2624
|
+
"",
|
|
2625
|
+
body,
|
|
2626
|
+
timestamp
|
|
2627
|
+
);
|
|
2628
|
+
return safeCompare(incoming, computed);
|
|
2629
|
+
}
|
|
2630
|
+
|
|
2631
|
+
// src/clients/snap.ts
|
|
2632
|
+
var SnapClient = class {
|
|
2633
|
+
options;
|
|
2634
|
+
token = null;
|
|
2635
|
+
tokenExpiry = 0;
|
|
2636
|
+
constructor(options) {
|
|
2637
|
+
this.options = {
|
|
2638
|
+
clientId: options.clientId || options.merchantCode || "",
|
|
2639
|
+
clientSecret: options.clientSecret || options.apiKey || options.serverKey || options.secretKey || "",
|
|
2640
|
+
privateKey: options.privateKey,
|
|
2641
|
+
sandbox: !!options.sandbox,
|
|
2642
|
+
merchantId: options.merchantId,
|
|
2643
|
+
terminalId: options.terminalId,
|
|
2644
|
+
partnerServiceId: options.partnerServiceId,
|
|
2645
|
+
channelId: options.channelId || "H2H"
|
|
2646
|
+
};
|
|
2647
|
+
}
|
|
2648
|
+
get baseUrl() {
|
|
2649
|
+
return this.options.sandbox ? "https://api-sandbox.doku.com" : "https://api.doku.com";
|
|
2650
|
+
}
|
|
2651
|
+
get isConfigured() {
|
|
2652
|
+
return Boolean(this.options.clientId && this.options.clientSecret);
|
|
2653
|
+
}
|
|
2654
|
+
/**
|
|
2655
|
+
* Get (cached) B2B access token. Mints a new one when expired.
|
|
2656
|
+
*/
|
|
2657
|
+
async getAccessToken() {
|
|
2658
|
+
const now = Date.now();
|
|
2659
|
+
if (this.token && now < this.tokenExpiry) {
|
|
2660
|
+
return this.token;
|
|
2661
|
+
}
|
|
2662
|
+
const { clientId, clientSecret, privateKey } = this.options;
|
|
2663
|
+
if (!privateKey) {
|
|
2664
|
+
throw new Error("DOKU SNAP: RSA privateKey required to obtain B2B access token");
|
|
2665
|
+
}
|
|
2666
|
+
const endpoint = "/authorization/v1/access-token/b2b";
|
|
2667
|
+
const timestamp = snapUtcTimestamp();
|
|
2668
|
+
const signature = generateSnapAsymmetricSignature(privateKey, clientId, timestamp);
|
|
2669
|
+
const response = await fetch(this.baseUrl + endpoint, {
|
|
2670
|
+
method: "POST",
|
|
2671
|
+
headers: {
|
|
2672
|
+
"Content-Type": "application/json",
|
|
2673
|
+
"X-CLIENT-KEY": clientId,
|
|
2674
|
+
"X-TIMESTAMP": timestamp,
|
|
2675
|
+
"X-SIGNATURE": signature
|
|
2676
|
+
},
|
|
2677
|
+
body: JSON.stringify({ grantType: "client_credentials" })
|
|
2678
|
+
});
|
|
2679
|
+
const text = await response.text();
|
|
2680
|
+
let data = null;
|
|
2681
|
+
try {
|
|
2682
|
+
data = JSON.parse(text);
|
|
2683
|
+
} catch {
|
|
2684
|
+
}
|
|
2685
|
+
if (!response.ok || !data?.accessToken) {
|
|
2686
|
+
throw new Error(data?.responseMessage || data?.message || `DOKU SNAP get-token failed: HTTP ${response.status} - ${text}`);
|
|
2687
|
+
}
|
|
2688
|
+
if (!clientSecret) {
|
|
2689
|
+
}
|
|
2690
|
+
this.token = data.accessToken;
|
|
2691
|
+
const expiresIn = Number(data.expiresIn || 900);
|
|
2692
|
+
this.tokenExpiry = now + (expiresIn - 30) * 1e3;
|
|
2693
|
+
return this.token;
|
|
2694
|
+
}
|
|
2695
|
+
clearToken() {
|
|
2696
|
+
this.token = null;
|
|
2697
|
+
this.tokenExpiry = 0;
|
|
2698
|
+
}
|
|
2699
|
+
/**
|
|
2700
|
+
* Perform a signed SNAP transaction request.
|
|
2701
|
+
* @param method GET/POST
|
|
2702
|
+
* @param endpoint request-target path (e.g. /virtual-accounts/...)
|
|
2703
|
+
* @param body request body (object)
|
|
2704
|
+
* @param opts extra headers (X-DEVICE-ID, X-IP-ADDRESS, etc.)
|
|
2705
|
+
*/
|
|
2706
|
+
async request(method, endpoint, body, opts = {}) {
|
|
2707
|
+
const { clientId, clientSecret, channelId } = this.options;
|
|
2708
|
+
if (!clientSecret) {
|
|
2709
|
+
throw new Error("DOKU SNAP: clientSecret (Secret Key) required for transaction signing");
|
|
2710
|
+
}
|
|
2711
|
+
const accessToken = await this.getAccessToken();
|
|
2712
|
+
const timestamp = snapTimestamp();
|
|
2713
|
+
const externalId = opts.externalId || snapExternalId();
|
|
2714
|
+
const payload = body === void 0 ? "" : body;
|
|
2715
|
+
const signature = generateSnapSymmetricSignature(
|
|
2716
|
+
clientSecret,
|
|
2717
|
+
method,
|
|
2718
|
+
endpoint,
|
|
2719
|
+
accessToken,
|
|
2720
|
+
payload,
|
|
2721
|
+
timestamp
|
|
2722
|
+
);
|
|
2723
|
+
const headers = {
|
|
2724
|
+
"Content-Type": "application/json",
|
|
2725
|
+
"X-PARTNER-ID": clientId,
|
|
2726
|
+
"X-EXTERNAL-ID": externalId,
|
|
2727
|
+
"X-TIMESTAMP": timestamp,
|
|
2728
|
+
"X-SIGNATURE": signature,
|
|
2729
|
+
"CHANNEL-ID": channelId || "H2H",
|
|
2730
|
+
"Authorization": `Bearer ${accessToken}`,
|
|
2731
|
+
...opts.deviceId ? { "X-DEVICE-ID": opts.deviceId } : {},
|
|
2732
|
+
...opts.ipAddress ? { "X-IP-ADDRESS": opts.ipAddress } : {},
|
|
2733
|
+
...opts.extraHeaders || {}
|
|
2734
|
+
};
|
|
2735
|
+
const response = await fetch(this.baseUrl + endpoint, {
|
|
2736
|
+
method,
|
|
2737
|
+
headers,
|
|
2738
|
+
body: method === "POST" && body !== void 0 ? JSON.stringify(body) : void 0
|
|
2739
|
+
});
|
|
2740
|
+
const text = await response.text();
|
|
2741
|
+
let data = null;
|
|
2742
|
+
try {
|
|
2743
|
+
data = JSON.parse(text);
|
|
2744
|
+
} catch {
|
|
2745
|
+
}
|
|
2746
|
+
if (!response.ok) {
|
|
2747
|
+
const err = data?.responseMessage || data?.error?.message || data?.message || `HTTP ${response.status}`;
|
|
2748
|
+
throw new Error(`${err}${data?.responseCode ? ` (${data.responseCode})` : ""}`);
|
|
2749
|
+
}
|
|
2750
|
+
return data;
|
|
2751
|
+
}
|
|
2752
|
+
};
|
|
2753
|
+
|
|
2566
2754
|
// src/providers/doku/provider.ts
|
|
2567
2755
|
var DokuProvider = class extends BasePaymentProvider {
|
|
2568
2756
|
name = "doku";
|
|
2569
2757
|
getBaseUrl(sandbox) {
|
|
2570
2758
|
return sandbox ? "https://api-sandbox.doku.com" : "https://api.doku.com";
|
|
2571
2759
|
}
|
|
2760
|
+
/**
|
|
2761
|
+
* DETEKSI mode integrasi DOKU:
|
|
2762
|
+
* - SNAP : kredensial baru (Client ID `doku_...` + Secret Key `SK-...`) + opsional RSA privateKey
|
|
2763
|
+
* untuk Get Token B2B. Diaktifkan via extra.snap / extra.dokuMode="snap" / doku_ prefix.
|
|
2764
|
+
* - Legacy: Jokul v2 (Client-Id + Signature HMAC-SHA256), default jika bukan SNAP.
|
|
2765
|
+
*/
|
|
2766
|
+
isSnap(config) {
|
|
2767
|
+
if (config.extra?.snap === true || config.extra?.snap === "true") return true;
|
|
2768
|
+
if (config.extra?.dokuMode === "snap") return true;
|
|
2769
|
+
const clientId = String(config.merchantCode || config.merchantId || config.clientKey || "").trim().toLowerCase();
|
|
2770
|
+
return /^doku[_:-]/.test(clientId);
|
|
2771
|
+
}
|
|
2772
|
+
buildSnap(config) {
|
|
2773
|
+
const clientId = config.merchantCode || config.merchantId || config.clientKey || "";
|
|
2774
|
+
const clientSecret = config.apiKey || config.serverKey || config.secretKey || "";
|
|
2775
|
+
return new SnapClient({
|
|
2776
|
+
clientId,
|
|
2777
|
+
clientSecret,
|
|
2778
|
+
privateKey: config.privateKey,
|
|
2779
|
+
sandbox: !!config.sandbox,
|
|
2780
|
+
merchantId: config.extra?.merchantId || config.projectId || "",
|
|
2781
|
+
terminalId: config.extra?.terminalId || "",
|
|
2782
|
+
partnerServiceId: config.extra?.partnerServiceId || "",
|
|
2783
|
+
channelId: config.extra?.channelId || "H2H"
|
|
2784
|
+
});
|
|
2785
|
+
}
|
|
2786
|
+
/** Helper: jumlah integer → format SNAP 2-desimal (".00"). */
|
|
2787
|
+
snapAmount(amount, currency = "IDR") {
|
|
2788
|
+
return { value: amount.toFixed(2), currency };
|
|
2789
|
+
}
|
|
2572
2790
|
async createInvoice(params, config) {
|
|
2573
2791
|
const { orderId, amount, productDetails, customer, returnUrl } = params;
|
|
2574
2792
|
const clientId = config.merchantCode || config.merchantId || config.clientKey || "";
|
|
@@ -2579,6 +2797,9 @@ var DokuProvider = class extends BasePaymentProvider {
|
|
|
2579
2797
|
const isDirect = !!dokuMethod;
|
|
2580
2798
|
const baseUrl = this.getBaseUrl(sandbox);
|
|
2581
2799
|
try {
|
|
2800
|
+
if (this.isSnap(config)) {
|
|
2801
|
+
return await this.createSnapInvoice(params, config, baseUrl);
|
|
2802
|
+
}
|
|
2582
2803
|
if (isDirect) {
|
|
2583
2804
|
const endpoint = dokuMethod.endpoint;
|
|
2584
2805
|
const url = `${baseUrl}${endpoint}`;
|
|
@@ -2766,7 +2987,178 @@ var DokuProvider = class extends BasePaymentProvider {
|
|
|
2766
2987
|
};
|
|
2767
2988
|
}
|
|
2768
2989
|
}
|
|
2990
|
+
/**
|
|
2991
|
+
* DOKU SNAP: buat transaksi (Create VA / Generate QRIS / e-Wallet Payment).
|
|
2992
|
+
* Autentikasi via B2B token + symmetric HMAC-SHA512 signature.
|
|
2993
|
+
*/
|
|
2994
|
+
async createSnapInvoice(params, config, baseUrl) {
|
|
2995
|
+
const { orderId, amount, productDetails, customer, returnUrl } = params;
|
|
2996
|
+
const snap = this.buildSnap(config);
|
|
2997
|
+
const integerAmount = Math.round(amount);
|
|
2998
|
+
const method = String(params.paymentMethod || "").toLowerCase();
|
|
2999
|
+
const bankMap = {
|
|
3000
|
+
bca: "VIRTUAL_ACCOUNT_BCA",
|
|
3001
|
+
mandiri: "VIRTUAL_ACCOUNT_BANK_MANDIRI",
|
|
3002
|
+
bri: "VIRTUAL_ACCOUNT_BRI",
|
|
3003
|
+
bni: "VIRTUAL_ACCOUNT_BNI",
|
|
3004
|
+
permata: "VIRTUAL_ACCOUNT_BANK_PERMATA",
|
|
3005
|
+
cimb: "VIRTUAL_ACCOUNT_BANK_CIMB",
|
|
3006
|
+
danamon: "VIRTUAL_ACCOUNT_BANK_DANAMON",
|
|
3007
|
+
bsi: "VIRTUAL_ACCOUNT_BANK_SYARIAH_MANDIRI",
|
|
3008
|
+
sinarmas: "VIRTUAL_ACCOUNT_SINARMAS",
|
|
3009
|
+
bjb: "VIRTUAL_ACCOUNT_BANK_BJB",
|
|
3010
|
+
btn: "VIRTUAL_ACCOUNT_BTN",
|
|
3011
|
+
bnc: "VIRTUAL_ACCOUNT_BNC"
|
|
3012
|
+
};
|
|
3013
|
+
const isVa = method.includes("_va");
|
|
3014
|
+
const isQris = method === "qris" || method.includes("qris");
|
|
3015
|
+
try {
|
|
3016
|
+
if (isVa) {
|
|
3017
|
+
return await this.snapCreateVA(params, config, snap, baseUrl, bankMap);
|
|
3018
|
+
}
|
|
3019
|
+
if (isQris) {
|
|
3020
|
+
return await this.snapGenerateQRIS(params, config, snap, baseUrl);
|
|
3021
|
+
}
|
|
3022
|
+
return await this.snapEWalletPayment(params, config, snap, baseUrl);
|
|
3023
|
+
} catch (e) {
|
|
3024
|
+
return {
|
|
3025
|
+
success: false,
|
|
3026
|
+
provider: "doku",
|
|
3027
|
+
orderId,
|
|
3028
|
+
amount: integerAmount,
|
|
3029
|
+
rawResponse: null,
|
|
3030
|
+
error: e.message || "Failed to make SNAP request to DOKU API"
|
|
3031
|
+
};
|
|
3032
|
+
}
|
|
3033
|
+
}
|
|
3034
|
+
/** Create Virtual Account (SNAP) — DOKU Generate Payment Code. */
|
|
3035
|
+
async snapCreateVA(params, config, snap, baseUrl, bankMap) {
|
|
3036
|
+
const { orderId, amount, productDetails, customer } = params;
|
|
3037
|
+
const method = String(params.paymentMethod || "").toLowerCase();
|
|
3038
|
+
const bankKey = method.replace(/_va$/, "");
|
|
3039
|
+
const channel = config.extra?.vaChannel || bankMap[bankKey] || `VIRTUAL_ACCOUNT_${bankKey.toUpperCase()}`;
|
|
3040
|
+
const partnerServiceId = (config.extra?.partnerServiceId || "").replace(/\s/g, "");
|
|
3041
|
+
const customerNo = (config.extra?.customerNo || "").slice(0, 20) || String(Date.now()).slice(-12);
|
|
3042
|
+
const virtualAccountNo = (partnerServiceId + customerNo).slice(0, 28);
|
|
3043
|
+
const reusable = config.extra?.reusableStatus === true;
|
|
3044
|
+
const currency = params.currency || "IDR";
|
|
3045
|
+
const body = {
|
|
3046
|
+
partnerServiceId,
|
|
3047
|
+
customerNo,
|
|
3048
|
+
virtualAccountNo,
|
|
3049
|
+
virtualAccountName: customer.name || "Customer",
|
|
3050
|
+
virtualAccountEmail: customer.email,
|
|
3051
|
+
virtualAccountPhone: customer.phone,
|
|
3052
|
+
trxId: orderId,
|
|
3053
|
+
totalAmount: this.snapAmount(amount, currency),
|
|
3054
|
+
virtualAccountTrxType: "C",
|
|
3055
|
+
additionalInfo: {
|
|
3056
|
+
channel,
|
|
3057
|
+
virtualAccountConfig: { reusableStatus: reusable }
|
|
3058
|
+
}
|
|
3059
|
+
};
|
|
3060
|
+
if (params.providerParams) {
|
|
3061
|
+
Object.assign(body.additionalInfo.virtualAccountConfig, params.providerParams);
|
|
3062
|
+
}
|
|
3063
|
+
if (config.extra?.expiredDate) body.expiredDate = config.extra.expiredDate;
|
|
3064
|
+
const endpoint = "/virtual-accounts/bi-snap-va/v1.1/transfer-va/create-va";
|
|
3065
|
+
const data = await snap.request("POST", endpoint, body);
|
|
3066
|
+
const vaData = data.virtualAccountData || {};
|
|
3067
|
+
return {
|
|
3068
|
+
success: true,
|
|
3069
|
+
provider: "doku",
|
|
3070
|
+
orderId: vaData.trxId || orderId,
|
|
3071
|
+
amount: Number(vaData.totalAmount?.value || amount) || Math.round(amount),
|
|
3072
|
+
reference: vaData.virtualAccountNo || orderId,
|
|
3073
|
+
vaNumber: vaData.virtualAccountNo,
|
|
3074
|
+
vaBank: bankKey.toUpperCase(),
|
|
3075
|
+
paymentUrl: vaData.additionalInfo?.howToPayPage,
|
|
3076
|
+
expiresAt: vaData.expiredDate ? new Date(vaData.expiredDate) : void 0,
|
|
3077
|
+
rawResponse: data
|
|
3078
|
+
};
|
|
3079
|
+
}
|
|
3080
|
+
/** Generate QRIS (SNAP) — dynamic QRIS MPM. */
|
|
3081
|
+
async snapGenerateQRIS(params, config, snap, baseUrl) {
|
|
3082
|
+
const { orderId, amount } = params;
|
|
3083
|
+
const currency = params.currency || "IDR";
|
|
3084
|
+
const merchantId = config.extra?.merchantId || config.projectId || "";
|
|
3085
|
+
const terminalId = config.extra?.terminalId || "0001";
|
|
3086
|
+
const body = {
|
|
3087
|
+
partnerReferenceNo: orderId,
|
|
3088
|
+
amount: this.snapAmount(amount, currency),
|
|
3089
|
+
merchantId,
|
|
3090
|
+
terminalId,
|
|
3091
|
+
validityPeriod: config.extra?.validityPeriod || new Date(Date.now() + 3600 * 1e3).toISOString(),
|
|
3092
|
+
additionalInfo: {
|
|
3093
|
+
postalCode: config.extra?.postalCode || "10110",
|
|
3094
|
+
feeType: 1
|
|
3095
|
+
}
|
|
3096
|
+
};
|
|
3097
|
+
if (params.providerParams) {
|
|
3098
|
+
Object.assign(body.additionalInfo, params.providerParams);
|
|
3099
|
+
}
|
|
3100
|
+
const endpoint = "/snap-adapter/b2b/v1.0/qr/qr-mpm-generate";
|
|
3101
|
+
const data = await snap.request("POST", endpoint, body);
|
|
3102
|
+
return {
|
|
3103
|
+
success: true,
|
|
3104
|
+
provider: "doku",
|
|
3105
|
+
orderId: data.partnerReferenceNo || orderId,
|
|
3106
|
+
amount: Number(data.amount?.value || amount) || Math.round(amount),
|
|
3107
|
+
reference: data.referenceNo || orderId,
|
|
3108
|
+
qrString: data.qrContent,
|
|
3109
|
+
rawResponse: data
|
|
3110
|
+
};
|
|
3111
|
+
}
|
|
3112
|
+
/** e-Wallet payment (SNAP) — DANA / OVO / ShopeePay via payment-host-to-host. */
|
|
3113
|
+
async snapEWalletPayment(params, config, snap, baseUrl) {
|
|
3114
|
+
const { orderId, amount } = params;
|
|
3115
|
+
const method = String(params.paymentMethod || "").toLowerCase();
|
|
3116
|
+
const currency = params.currency || "IDR";
|
|
3117
|
+
const returnUrl = params.returnUrl || config.returnUrl || "";
|
|
3118
|
+
const channelMap = {
|
|
3119
|
+
dana: "EMONEY_DANA_SNAP",
|
|
3120
|
+
ovo: "EMONEY_OVO_SNAP",
|
|
3121
|
+
shopeepay: "EMONEY_SHOPEEPAY_SNAP"
|
|
3122
|
+
};
|
|
3123
|
+
const channel = config.extra?.ewalletChannel || channelMap[method] || `EMONEY_${method.toUpperCase()}_SNAP`;
|
|
3124
|
+
const body = {
|
|
3125
|
+
partnerReferenceNo: orderId,
|
|
3126
|
+
amount: this.snapAmount(amount, currency),
|
|
3127
|
+
pointOfInitiation: "pc",
|
|
3128
|
+
urlParam: {
|
|
3129
|
+
url: returnUrl || "https://example.com/return",
|
|
3130
|
+
type: "PAY_RETURN",
|
|
3131
|
+
isDeepLink: "N"
|
|
3132
|
+
},
|
|
3133
|
+
additionalInfo: {
|
|
3134
|
+
channel,
|
|
3135
|
+
orderTitle: params.productDetails || `Pembayaran ${orderId}`,
|
|
3136
|
+
supportDeepLinkCheckoutUrl: "false"
|
|
3137
|
+
}
|
|
3138
|
+
};
|
|
3139
|
+
if (params.providerParams) {
|
|
3140
|
+
Object.assign(body.additionalInfo, params.providerParams);
|
|
3141
|
+
}
|
|
3142
|
+
const endpoint = "/direct-debit/core/v1/debit/payment-host-to-host";
|
|
3143
|
+
const data = await snap.request("POST", endpoint, body, {
|
|
3144
|
+
deviceId: config.extra?.deviceId,
|
|
3145
|
+
ipAddress: config.extra?.ipAddress
|
|
3146
|
+
});
|
|
3147
|
+
return {
|
|
3148
|
+
success: true,
|
|
3149
|
+
provider: "doku",
|
|
3150
|
+
orderId: data.partnerReferenceNo || orderId,
|
|
3151
|
+
amount: Number(data.amount?.value || amount) || Math.round(amount),
|
|
3152
|
+
reference: data.partnerReferenceNo || orderId,
|
|
3153
|
+
paymentUrl: data.webRedirectUrl || data.paymentUrl,
|
|
3154
|
+
rawResponse: data
|
|
3155
|
+
};
|
|
3156
|
+
}
|
|
2769
3157
|
async verifyCallback(body, config) {
|
|
3158
|
+
const headers = config.extra?.headers || {};
|
|
3159
|
+
if (this.isSnap(config)) {
|
|
3160
|
+
return this.verifySnapCallback(body, config, headers);
|
|
3161
|
+
}
|
|
2770
3162
|
const rawStatus = (body.transaction?.status || body.status || "").toUpperCase();
|
|
2771
3163
|
const isPaid = rawStatus === "SUCCESS" || rawStatus === "PAID" || rawStatus === "SETTLED";
|
|
2772
3164
|
const isPending = rawStatus === "PENDING";
|
|
@@ -2776,7 +3168,6 @@ var DokuProvider = class extends BasePaymentProvider {
|
|
|
2776
3168
|
const amount = body.order?.amount || body.amount || 0;
|
|
2777
3169
|
const status = isPaid ? "paid" : isPending ? "pending" : isExpired ? "expired" : "failed";
|
|
2778
3170
|
const secretKey = config.secretKey || config.apiKey || "";
|
|
2779
|
-
const headers = config.extra?.headers || {};
|
|
2780
3171
|
const signature = headers["signature"] || headers["Signature"] || config.extra?.dokuSignature || config.extra?.signatureHeader;
|
|
2781
3172
|
const clientId = config.merchantCode || config.clientKey || "";
|
|
2782
3173
|
let isValid = true;
|
|
@@ -2797,6 +3188,40 @@ var DokuProvider = class extends BasePaymentProvider {
|
|
|
2797
3188
|
rawPayload: body
|
|
2798
3189
|
};
|
|
2799
3190
|
}
|
|
3191
|
+
/**
|
|
3192
|
+
* Verifikasi webhook / notifikasi DOKU SNAP.
|
|
3193
|
+
* Signature dibangun dengan symmetric HMAC-SHA512 (AccessToken kosong).
|
|
3194
|
+
*/
|
|
3195
|
+
verifySnapCallback(body, config, headers) {
|
|
3196
|
+
const clientSecret = config.apiKey || config.serverKey || config.secretKey || "";
|
|
3197
|
+
const endpointUrl = config.extra?.notificationPath || headers["x-path"] || config.extra?.headers?.["request-target"] || "/api/payment/webhook";
|
|
3198
|
+
let isValid = true;
|
|
3199
|
+
const incomingSig = headers["x-signature"] || headers["X-SIGNATURE"] || headers["signature"] || headers["Signature"] || "";
|
|
3200
|
+
if (incomingSig && clientSecret) {
|
|
3201
|
+
isValid = verifySnapWebhookSignature(headers, body, clientSecret, endpointUrl);
|
|
3202
|
+
}
|
|
3203
|
+
const explicitStatus = String(body.transactionStatus || body.status || body.latestTransactionStatus || "").toUpperCase();
|
|
3204
|
+
const isPaid = explicitStatus === "SUCCESS" || explicitStatus === "PAID" || explicitStatus === "SETTLED" || explicitStatus === "00" || !explicitStatus && Boolean(body.paidAmount?.value ?? body.totalAmount?.value);
|
|
3205
|
+
const isPending = explicitStatus === "PENDING" || explicitStatus === "11" || explicitStatus === "ONGOING";
|
|
3206
|
+
const isFailed = explicitStatus === "FAILED" || explicitStatus === "DECLINED" || Boolean(explicitStatus) && !isPaid && !isPending && explicitStatus !== "00";
|
|
3207
|
+
const isExpired = explicitStatus === "EXPIRED";
|
|
3208
|
+
const orderId = body.trxId || body.partnerReferenceNo || body.originalPartnerReferenceNo || body.order?.invoice_number || body.invoice_number || body.order_id || "";
|
|
3209
|
+
const paidValue = body.paidAmount?.value ?? body.totalAmount?.value ?? body.amount?.value ?? body.amount ?? 0;
|
|
3210
|
+
const status = isPaid ? "paid" : isPending ? "pending" : isExpired ? "expired" : "failed";
|
|
3211
|
+
return {
|
|
3212
|
+
isValid,
|
|
3213
|
+
provider: "doku",
|
|
3214
|
+
orderId: String(orderId),
|
|
3215
|
+
amount: Number(paidValue) || 0,
|
|
3216
|
+
status,
|
|
3217
|
+
isPaid,
|
|
3218
|
+
isPending,
|
|
3219
|
+
isFailed,
|
|
3220
|
+
isExpired,
|
|
3221
|
+
statusCode: explicitStatus || "SUCCESS",
|
|
3222
|
+
rawPayload: body
|
|
3223
|
+
};
|
|
3224
|
+
}
|
|
2800
3225
|
async getPaymentMethods(params, config) {
|
|
2801
3226
|
const staticMethods = [
|
|
2802
3227
|
{
|
|
@@ -2956,6 +3381,9 @@ var DokuProvider = class extends BasePaymentProvider {
|
|
|
2956
3381
|
const clientId = config.merchantCode || config.merchantId || config.clientKey || "";
|
|
2957
3382
|
const secretKey = config.apiKey || config.serverKey || config.secretKey || "";
|
|
2958
3383
|
const sandbox = !!config.sandbox;
|
|
3384
|
+
if (this.isSnap(config)) {
|
|
3385
|
+
return this.snapCheckTransaction(params, config, clientId);
|
|
3386
|
+
}
|
|
2959
3387
|
const endpoint = `/orders/v1/status/${merchantOrderId}`;
|
|
2960
3388
|
const url = `${this.getBaseUrl(sandbox)}${endpoint}`;
|
|
2961
3389
|
const headers = generateDokuHeaders(clientId, secretKey, endpoint);
|
|
@@ -3033,6 +3461,58 @@ var DokuProvider = class extends BasePaymentProvider {
|
|
|
3033
3461
|
};
|
|
3034
3462
|
}
|
|
3035
3463
|
}
|
|
3464
|
+
/** Cek status transaksi SNAP (menggunakan Query QRIS bila ref berasal dari QRIS). */
|
|
3465
|
+
async snapCheckTransaction(params, config, clientId) {
|
|
3466
|
+
const { merchantOrderId } = params;
|
|
3467
|
+
const snap = this.buildSnap(config);
|
|
3468
|
+
try {
|
|
3469
|
+
const body = {
|
|
3470
|
+
originalPartnerReferenceNo: merchantOrderId,
|
|
3471
|
+
serviceCode: "47",
|
|
3472
|
+
merchantId: config.extra?.merchantId || config.projectId || ""
|
|
3473
|
+
};
|
|
3474
|
+
const data = await snap.request("POST", "/snap-adapter/b2b/v1.0/qr/qr-mpm-query", body);
|
|
3475
|
+
const txStatus = String(data.latestTransactionStatus || "").toUpperCase();
|
|
3476
|
+
const isPaid = txStatus === "SUCCESS" || txStatus === "00" || txStatus === "PAID" || txStatus === "SETTLED";
|
|
3477
|
+
const isPending = txStatus === "PENDING" || txStatus === "ONGOING" || txStatus === "11";
|
|
3478
|
+
const isExpired = txStatus === "EXPIRED";
|
|
3479
|
+
const isFailed = txStatus === "FAILED" || txStatus === "DECLINED" || Boolean(txStatus) && !isPaid && !isPending && !isExpired;
|
|
3480
|
+
const status = isPaid ? "paid" : isPending ? "pending" : isExpired ? "expired" : "failed";
|
|
3481
|
+
return {
|
|
3482
|
+
success: true,
|
|
3483
|
+
provider: "doku",
|
|
3484
|
+
orderId: data.originalPartnerReferenceNo || merchantOrderId,
|
|
3485
|
+
reference: data.originalReferenceNo || "",
|
|
3486
|
+
amount: Number(data.amount?.value || 0),
|
|
3487
|
+
statusCode: txStatus || String(data.responseCode || ""),
|
|
3488
|
+
status,
|
|
3489
|
+
isPaid,
|
|
3490
|
+
isPending,
|
|
3491
|
+
isFailed,
|
|
3492
|
+
isExpired,
|
|
3493
|
+
statusMessage: txStatus || data.responseMessage || "",
|
|
3494
|
+
paymentType: "QRIS",
|
|
3495
|
+
rawResponse: data
|
|
3496
|
+
};
|
|
3497
|
+
} catch (e) {
|
|
3498
|
+
return {
|
|
3499
|
+
success: false,
|
|
3500
|
+
provider: "doku",
|
|
3501
|
+
orderId: merchantOrderId,
|
|
3502
|
+
reference: "",
|
|
3503
|
+
amount: 0,
|
|
3504
|
+
statusCode: "ERROR",
|
|
3505
|
+
status: "failed",
|
|
3506
|
+
isPaid: false,
|
|
3507
|
+
isPending: false,
|
|
3508
|
+
isFailed: true,
|
|
3509
|
+
isExpired: false,
|
|
3510
|
+
statusMessage: e.message || "Failed to check SNAP transaction status",
|
|
3511
|
+
error: e.message || "Failed to check SNAP transaction status",
|
|
3512
|
+
rawResponse: null
|
|
3513
|
+
};
|
|
3514
|
+
}
|
|
3515
|
+
}
|
|
3036
3516
|
};
|
|
3037
3517
|
|
|
3038
3518
|
// src/providers/prismalink/signature.ts
|
|
@@ -3426,15 +3906,15 @@ var PrismalinkProvider = class extends BasePaymentProvider {
|
|
|
3426
3906
|
};
|
|
3427
3907
|
|
|
3428
3908
|
// src/providers/faspay/signature.ts
|
|
3429
|
-
var
|
|
3909
|
+
var import_crypto11 = __toESM(require("crypto"));
|
|
3430
3910
|
function generateFaspaySignature(userId, password, billNo) {
|
|
3431
|
-
const md5Hash =
|
|
3432
|
-
return
|
|
3911
|
+
const md5Hash = import_crypto11.default.createHash("md5").update(`${userId}${password}${billNo}`).digest("hex");
|
|
3912
|
+
return import_crypto11.default.createHash("sha1").update(md5Hash).digest("hex");
|
|
3433
3913
|
}
|
|
3434
3914
|
function verifyFaspaySignature(userId, password, billNo, paymentStatusCode, incomingSignature) {
|
|
3435
3915
|
if (!incomingSignature || !password) return false;
|
|
3436
|
-
const md5Hash =
|
|
3437
|
-
const computed =
|
|
3916
|
+
const md5Hash = import_crypto11.default.createHash("md5").update(`${userId}${password}${billNo}${paymentStatusCode}`).digest("hex");
|
|
3917
|
+
const computed = import_crypto11.default.createHash("sha1").update(md5Hash).digest("hex");
|
|
3438
3918
|
const simpleComputed = generateFaspaySignature(userId, password, billNo);
|
|
3439
3919
|
return safeCompare(incomingSignature, computed) || safeCompare(incomingSignature, simpleComputed);
|
|
3440
3920
|
}
|
|
@@ -3847,10 +4327,10 @@ var FaspayProvider = class extends BasePaymentProvider {
|
|
|
3847
4327
|
};
|
|
3848
4328
|
|
|
3849
4329
|
// src/providers/finpay/signature.ts
|
|
3850
|
-
var
|
|
4330
|
+
var import_crypto13 = __toESM(require("crypto"));
|
|
3851
4331
|
function generateFinpaySignature(merchantId, orderId, amount, merchantKey) {
|
|
3852
4332
|
const data = `${merchantId}%${orderId}%${Math.round(amount)}%${merchantKey}`;
|
|
3853
|
-
return
|
|
4333
|
+
return import_crypto13.default.createHmac("sha512", merchantKey).update(data).digest("hex");
|
|
3854
4334
|
}
|
|
3855
4335
|
function verifyFinpaySignature(merchantId, orderId, amount, merchantKey, incomingSignature) {
|
|
3856
4336
|
if (!incomingSignature || !merchantKey) return false;
|
|
@@ -5747,7 +6227,7 @@ var PaypalProvider = class extends BasePaymentProvider {
|
|
|
5747
6227
|
};
|
|
5748
6228
|
|
|
5749
6229
|
// src/providers/adyen/signature.ts
|
|
5750
|
-
var
|
|
6230
|
+
var import_crypto18 = require("crypto");
|
|
5751
6231
|
function verifyAdyenWebhook(notificationItem, hmacKey) {
|
|
5752
6232
|
if (!hmacKey || !notificationItem) return false;
|
|
5753
6233
|
try {
|
|
@@ -5764,7 +6244,7 @@ function verifyAdyenWebhook(notificationItem, hmacKey) {
|
|
|
5764
6244
|
];
|
|
5765
6245
|
const signedData = fields.join(":");
|
|
5766
6246
|
const keyBytes = Buffer.from(hmacKey, "hex");
|
|
5767
|
-
const expected = (0,
|
|
6247
|
+
const expected = (0, import_crypto18.createHmac)("sha256", keyBytes).update(signedData, "utf8").digest("base64");
|
|
5768
6248
|
const provided = notificationItem.additionalData?.hmacSignature || "";
|
|
5769
6249
|
return safeCompare(expected, provided);
|
|
5770
6250
|
} catch {
|
|
@@ -5997,11 +6477,11 @@ var AdyenProvider = class extends BasePaymentProvider {
|
|
|
5997
6477
|
};
|
|
5998
6478
|
|
|
5999
6479
|
// src/providers/checkoutcom/signature.ts
|
|
6000
|
-
var
|
|
6480
|
+
var import_crypto20 = require("crypto");
|
|
6001
6481
|
function verifyCheckoutComWebhook(body, signatureHeader, secret) {
|
|
6002
6482
|
if (!secret || !signatureHeader || !body) return false;
|
|
6003
6483
|
try {
|
|
6004
|
-
const expected = (0,
|
|
6484
|
+
const expected = (0, import_crypto20.createHmac)("sha256", secret).update(body, "utf8").digest("hex");
|
|
6005
6485
|
const provided = signatureHeader.replace(/^sha256=/, "");
|
|
6006
6486
|
return safeCompare(expected, provided);
|
|
6007
6487
|
} catch {
|
|
@@ -6221,11 +6701,11 @@ var CheckoutComProvider = class extends BasePaymentProvider {
|
|
|
6221
6701
|
};
|
|
6222
6702
|
|
|
6223
6703
|
// src/providers/razorpay/signature.ts
|
|
6224
|
-
var
|
|
6704
|
+
var import_crypto22 = require("crypto");
|
|
6225
6705
|
function verifyRazorpayWebhook(rawBody, signature, webhookSecret) {
|
|
6226
6706
|
if (!webhookSecret || !signature || !rawBody) return false;
|
|
6227
6707
|
try {
|
|
6228
|
-
const expected = (0,
|
|
6708
|
+
const expected = (0, import_crypto22.createHmac)("sha256", webhookSecret).update(rawBody).digest("hex");
|
|
6229
6709
|
return safeCompare(expected, signature);
|
|
6230
6710
|
} catch {
|
|
6231
6711
|
return false;
|
|
@@ -6451,12 +6931,12 @@ var RazorpayProvider = class extends BasePaymentProvider {
|
|
|
6451
6931
|
};
|
|
6452
6932
|
|
|
6453
6933
|
// src/providers/square/signature.ts
|
|
6454
|
-
var
|
|
6934
|
+
var import_crypto24 = require("crypto");
|
|
6455
6935
|
function verifySquareWebhook(rawBody, signatureHeader, signatureKey, notificationUrl) {
|
|
6456
6936
|
if (!signatureKey || !signatureHeader || !rawBody) return false;
|
|
6457
6937
|
try {
|
|
6458
6938
|
const payload = notificationUrl + rawBody;
|
|
6459
|
-
const expected = (0,
|
|
6939
|
+
const expected = (0, import_crypto24.createHmac)("sha256", signatureKey).update(payload).digest("base64");
|
|
6460
6940
|
return safeCompare(expected, signatureHeader);
|
|
6461
6941
|
} catch {
|
|
6462
6942
|
return false;
|
|
@@ -6696,7 +7176,7 @@ var SquareProvider = class extends BasePaymentProvider {
|
|
|
6696
7176
|
};
|
|
6697
7177
|
|
|
6698
7178
|
// src/providers/payu/signature.ts
|
|
6699
|
-
var
|
|
7179
|
+
var import_crypto26 = require("crypto");
|
|
6700
7180
|
function verifyPayuWebhook(rawBody, signatureHeader, md5Key) {
|
|
6701
7181
|
if (!md5Key || !signatureHeader || !rawBody) return false;
|
|
6702
7182
|
try {
|
|
@@ -6709,10 +7189,10 @@ function verifyPayuWebhook(rawBody, signatureHeader, md5Key) {
|
|
|
6709
7189
|
const algorithm = (parts["algorithm"] || "MD5").toUpperCase();
|
|
6710
7190
|
if (!providedSig) return false;
|
|
6711
7191
|
if (algorithm === "MD5") {
|
|
6712
|
-
const expected = (0,
|
|
7192
|
+
const expected = (0, import_crypto26.createHash)("md5").update(rawBody + md5Key).digest("hex");
|
|
6713
7193
|
return safeCompare(expected, providedSig);
|
|
6714
7194
|
} else if (algorithm === "SHA-256") {
|
|
6715
|
-
const expected = (0,
|
|
7195
|
+
const expected = (0, import_crypto26.createHash)("sha256").update(rawBody + md5Key).digest("hex");
|
|
6716
7196
|
return safeCompare(expected, providedSig);
|
|
6717
7197
|
}
|
|
6718
7198
|
return false;
|
|
@@ -6988,7 +7468,7 @@ var PayuProvider = class extends BasePaymentProvider {
|
|
|
6988
7468
|
};
|
|
6989
7469
|
|
|
6990
7470
|
// src/providers/braintree/signature.ts
|
|
6991
|
-
var
|
|
7471
|
+
var import_crypto28 = require("crypto");
|
|
6992
7472
|
function verifyBraintreeWebhook(btSignature, btPayload, privateKey) {
|
|
6993
7473
|
if (!privateKey || !btSignature || !btPayload) return false;
|
|
6994
7474
|
try {
|
|
@@ -6996,8 +7476,8 @@ function verifyBraintreeWebhook(btSignature, btPayload, privateKey) {
|
|
|
6996
7476
|
if (parts.length < 2) return false;
|
|
6997
7477
|
const providedHmac = parts[1];
|
|
6998
7478
|
const payload = Buffer.from(btPayload, "base64").toString("utf8");
|
|
6999
|
-
const secretHash = (0,
|
|
7000
|
-
const expected = (0,
|
|
7479
|
+
const secretHash = (0, import_crypto28.createHash)("sha1").update(privateKey).digest("hex");
|
|
7480
|
+
const expected = (0, import_crypto28.createHmac)("sha1", secretHash).update(payload).digest("hex");
|
|
7001
7481
|
return safeCompare(expected, providedHmac);
|
|
7002
7482
|
} catch {
|
|
7003
7483
|
return false;
|
|
@@ -7224,11 +7704,11 @@ var BraintreeProvider = class extends BasePaymentProvider {
|
|
|
7224
7704
|
};
|
|
7225
7705
|
|
|
7226
7706
|
// src/providers/twocheckout/signature.ts
|
|
7227
|
-
var
|
|
7707
|
+
var import_crypto30 = require("crypto");
|
|
7228
7708
|
function buildTwoCheckoutAuth(merchantCode, secretKey) {
|
|
7229
7709
|
const date = Math.floor(Date.now() / 1e3).toString();
|
|
7230
7710
|
const raw = merchantCode + date;
|
|
7231
|
-
const hmac = (0,
|
|
7711
|
+
const hmac = (0, import_crypto30.createHmac)("sha256", secretKey).update(raw).digest("hex");
|
|
7232
7712
|
const header = `code="${merchantCode}" date="${date}" hash="${hmac}"`;
|
|
7233
7713
|
return { header, date };
|
|
7234
7714
|
}
|
|
@@ -7236,7 +7716,7 @@ function verifyTwoCheckoutWebhook(secretWord, saleId, productId, invoiceId, prov
|
|
|
7236
7716
|
if (!secretWord || !providedHash) return false;
|
|
7237
7717
|
try {
|
|
7238
7718
|
const raw = secretWord + saleId + productId + invoiceId;
|
|
7239
|
-
const expected = (0,
|
|
7719
|
+
const expected = (0, import_crypto30.createHash)("md5").update(raw).digest("hex");
|
|
7240
7720
|
return safeCompare(expected, providedHash);
|
|
7241
7721
|
} catch {
|
|
7242
7722
|
return false;
|
|
@@ -9593,6 +10073,7 @@ var buayar = new Buayar();
|
|
|
9593
10073
|
PrismalinkProvider,
|
|
9594
10074
|
RazorpayClient,
|
|
9595
10075
|
RazorpayProvider,
|
|
10076
|
+
SnapClient,
|
|
9596
10077
|
SquareClient,
|
|
9597
10078
|
SquareProvider,
|
|
9598
10079
|
StripeClient,
|
|
@@ -9616,6 +10097,8 @@ var buayar = new Buayar();
|
|
|
9616
10097
|
generateNicepayToken,
|
|
9617
10098
|
generateOyHeaders,
|
|
9618
10099
|
generatePrismalinkSignature,
|
|
10100
|
+
generateSnapAsymmetricSignature,
|
|
10101
|
+
generateSnapSymmetricSignature,
|
|
9619
10102
|
getDuitkuInquirySignatures,
|
|
9620
10103
|
getDuitkuPaymentMethodsSignature,
|
|
9621
10104
|
getDuitkuStatusSignatures,
|
|
@@ -9623,6 +10106,7 @@ var buayar = new Buayar();
|
|
|
9623
10106
|
getXenditAuthHeader,
|
|
9624
10107
|
hmacSha256,
|
|
9625
10108
|
md5,
|
|
10109
|
+
minifyJson,
|
|
9626
10110
|
parseCoreChargeResponse,
|
|
9627
10111
|
paymentManager,
|
|
9628
10112
|
resolveConfigFromEnv,
|
|
@@ -9630,7 +10114,11 @@ var buayar = new Buayar();
|
|
|
9630
10114
|
serializePaypalParams,
|
|
9631
10115
|
serializeStripeParams,
|
|
9632
10116
|
sha256,
|
|
10117
|
+
sha256Hex,
|
|
9633
10118
|
sha512,
|
|
10119
|
+
snapExternalId,
|
|
10120
|
+
snapTimestamp,
|
|
10121
|
+
snapUtcTimestamp,
|
|
9634
10122
|
toCanonicalPaymentMethod,
|
|
9635
10123
|
toDokuPaymentMethod,
|
|
9636
10124
|
toDuitkuPaymentMethod,
|
|
@@ -9656,6 +10144,7 @@ var buayar = new Buayar();
|
|
|
9656
10144
|
verifyPayuWebhook,
|
|
9657
10145
|
verifyPrismalinkSignature,
|
|
9658
10146
|
verifyRazorpayWebhook,
|
|
10147
|
+
verifySnapWebhookSignature,
|
|
9659
10148
|
verifySquareWebhook,
|
|
9660
10149
|
verifyStripeWebhook,
|
|
9661
10150
|
verifyTwoCheckoutWebhook,
|