@crediblemark/buayar 0.2.0 → 0.2.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.mjs CHANGED
@@ -281,6 +281,17 @@ var CANONICAL_TO_OY = {
281
281
  alfamart: { type: "cstore", channel: "alfamart" },
282
282
  indomaret: { type: "cstore", channel: "indomaret" }
283
283
  };
284
+ var CANONICAL_TO_STRIPE = {
285
+ credit_card: "card",
286
+ qris: "qris",
287
+ gopay_qris: "qris",
288
+ shopeepay_qris: "qris",
289
+ bca_va: "customer_balance",
290
+ mandiri_va: "customer_balance",
291
+ bni_va: "customer_balance",
292
+ bri_va: "customer_balance",
293
+ permata_va: "customer_balance"
294
+ };
284
295
  function toDuitkuPaymentMethod(code) {
285
296
  if (!code) return void 0;
286
297
  const lower = code.toLowerCase().trim();
@@ -368,6 +379,14 @@ function toOyPaymentMethod(code) {
368
379
  }
369
380
  return void 0;
370
381
  }
382
+ function toStripePaymentMethod(code) {
383
+ if (!code) return void 0;
384
+ const lower = code.toLowerCase().trim();
385
+ if (CANONICAL_TO_STRIPE[lower]) {
386
+ return CANONICAL_TO_STRIPE[lower];
387
+ }
388
+ return lower;
389
+ }
371
390
  function toCanonicalPaymentMethod(provider, code) {
372
391
  if (!code) return "";
373
392
  const upper = code.toUpperCase().trim();
@@ -375,7 +394,7 @@ function toCanonicalPaymentMethod(provider, code) {
375
394
  if (provider.toLowerCase() === "duitku" && DUITKU_TO_CANONICAL[upper]) {
376
395
  return DUITKU_TO_CANONICAL[upper];
377
396
  }
378
- if (CANONICAL_TO_MIDTRANS[lower] || CANONICAL_TO_DUITKU[lower] || CANONICAL_TO_IPAYMU[lower] || CANONICAL_TO_XENDIT[lower] || CANONICAL_TO_DOKU[lower] || CANONICAL_TO_PRISMALINK[lower] || CANONICAL_TO_FASPAY[lower] || CANONICAL_TO_FINPAY[lower] || CANONICAL_TO_NICEPAY[lower] || CANONICAL_TO_OY[lower]) {
397
+ if (CANONICAL_TO_MIDTRANS[lower] || CANONICAL_TO_DUITKU[lower] || CANONICAL_TO_IPAYMU[lower] || CANONICAL_TO_XENDIT[lower] || CANONICAL_TO_DOKU[lower] || CANONICAL_TO_PRISMALINK[lower] || CANONICAL_TO_FASPAY[lower] || CANONICAL_TO_FINPAY[lower] || CANONICAL_TO_NICEPAY[lower] || CANONICAL_TO_OY[lower] || CANONICAL_TO_STRIPE[lower]) {
379
398
  return lower;
380
399
  }
381
400
  return lower;
@@ -4886,6 +4905,368 @@ var OyProvider = class extends BasePaymentProvider {
4886
4905
  }
4887
4906
  };
4888
4907
 
4908
+ // src/providers/stripe/signature.ts
4909
+ function serializeStripeParams(obj, prefix = "") {
4910
+ const pairs = [];
4911
+ if (obj === null || obj === void 0) {
4912
+ return "";
4913
+ }
4914
+ for (const key of Object.keys(obj)) {
4915
+ const val = obj[key];
4916
+ if (val === void 0 || val === null) continue;
4917
+ const fullKey = prefix ? `${prefix}[${key}]` : key;
4918
+ if (typeof val === "object" && !(val instanceof Date)) {
4919
+ const nested = serializeStripeParams(val, fullKey);
4920
+ if (nested) pairs.push(nested);
4921
+ } else {
4922
+ pairs.push(`${encodeURIComponent(fullKey)}=${encodeURIComponent(String(val))}`);
4923
+ }
4924
+ }
4925
+ return pairs.join("&");
4926
+ }
4927
+ function verifyStripeWebhook(rawPayload, signatureHeader, webhookSecret, toleranceSeconds = 300) {
4928
+ if (!signatureHeader || !webhookSecret) {
4929
+ return true;
4930
+ }
4931
+ const items = signatureHeader.split(",");
4932
+ let timestamp = "";
4933
+ const signatures = [];
4934
+ for (const item of items) {
4935
+ const [key, value] = item.trim().split("=");
4936
+ if (key === "t") {
4937
+ timestamp = value;
4938
+ } else if (key === "v1") {
4939
+ signatures.push(value);
4940
+ }
4941
+ }
4942
+ if (!timestamp || signatures.length === 0) {
4943
+ return false;
4944
+ }
4945
+ const payloadString = typeof rawPayload === "string" ? rawPayload : JSON.stringify(rawPayload);
4946
+ const signedPayload = `${timestamp}.${payloadString}`;
4947
+ const expectedSignature = hmacSha256(signedPayload, webhookSecret);
4948
+ return signatures.some((sig) => safeCompare(sig.toLowerCase(), expectedSignature.toLowerCase()));
4949
+ }
4950
+
4951
+ // src/providers/stripe/provider.ts
4952
+ var StripeProvider = class extends BasePaymentProvider {
4953
+ name = "stripe";
4954
+ getBaseUrl() {
4955
+ return "https://api.stripe.com/v1";
4956
+ }
4957
+ async createInvoice(params, config) {
4958
+ const { orderId, amount, productDetails, customer, returnUrl } = params;
4959
+ const secretKey = config.apiKey || config.serverKey || config.secretKey || "";
4960
+ const integerAmount = Math.round(amount);
4961
+ const stripeMethod = toStripePaymentMethod(params.paymentMethod);
4962
+ const isDirect = !!params.paymentMethod;
4963
+ const baseUrl = this.getBaseUrl();
4964
+ const headers = {
4965
+ "Authorization": `Bearer ${secretKey}`,
4966
+ "Content-Type": "application/x-www-form-urlencoded"
4967
+ };
4968
+ try {
4969
+ if (isDirect) {
4970
+ const url = `${baseUrl}/payment_intents`;
4971
+ const payload = {
4972
+ amount: integerAmount,
4973
+ currency: (params.currency || "idr").toLowerCase(),
4974
+ description: productDetails,
4975
+ receipt_email: customer?.email,
4976
+ payment_method_types: [stripeMethod || "card"],
4977
+ metadata: {
4978
+ order_id: orderId,
4979
+ customer_name: customer?.name
4980
+ },
4981
+ ...params.providerParams
4982
+ };
4983
+ const response = await fetch(url, {
4984
+ method: "POST",
4985
+ headers,
4986
+ body: serializeStripeParams(payload)
4987
+ });
4988
+ const text = await response.text();
4989
+ let data = null;
4990
+ try {
4991
+ data = JSON.parse(text);
4992
+ } catch (e) {
4993
+ }
4994
+ if (!response.ok || !data || data.error) {
4995
+ return {
4996
+ success: false,
4997
+ provider: "stripe",
4998
+ orderId,
4999
+ amount: integerAmount,
5000
+ rawResponse: data,
5001
+ error: data?.error?.message || `HTTP error! Status: ${response.status} - ${text}`
5002
+ };
5003
+ }
5004
+ return {
5005
+ success: true,
5006
+ provider: "stripe",
5007
+ orderId,
5008
+ amount: data.amount ? Number(data.amount) : integerAmount,
5009
+ reference: data.id,
5010
+ paymentCode: data.client_secret,
5011
+ rawResponse: data
5012
+ };
5013
+ } else {
5014
+ const url = `${baseUrl}/checkout/sessions`;
5015
+ const successUrl = returnUrl || config.returnUrl || "https://example.com/payment/success";
5016
+ const cancelUrl = returnUrl || config.returnUrl || "https://example.com/payment/cancel";
5017
+ const payload = {
5018
+ mode: "payment",
5019
+ client_reference_id: orderId,
5020
+ customer_email: customer?.email,
5021
+ line_items: [
5022
+ {
5023
+ price_data: {
5024
+ currency: (params.currency || "idr").toLowerCase(),
5025
+ product_data: {
5026
+ name: productDetails
5027
+ },
5028
+ unit_amount: integerAmount
5029
+ },
5030
+ quantity: 1
5031
+ }
5032
+ ],
5033
+ metadata: {
5034
+ order_id: orderId
5035
+ },
5036
+ success_url: successUrl,
5037
+ cancel_url: cancelUrl,
5038
+ ...params.providerParams
5039
+ };
5040
+ const response = await fetch(url, {
5041
+ method: "POST",
5042
+ headers,
5043
+ body: serializeStripeParams(payload)
5044
+ });
5045
+ const text = await response.text();
5046
+ let data = null;
5047
+ try {
5048
+ data = JSON.parse(text);
5049
+ } catch (e) {
5050
+ }
5051
+ if (!response.ok || !data || data.error) {
5052
+ return {
5053
+ success: false,
5054
+ provider: "stripe",
5055
+ orderId,
5056
+ amount: integerAmount,
5057
+ rawResponse: data,
5058
+ error: data?.error?.message || `HTTP error! Status: ${response.status} - ${text}`
5059
+ };
5060
+ }
5061
+ return {
5062
+ success: true,
5063
+ provider: "stripe",
5064
+ orderId: data.client_reference_id || orderId,
5065
+ amount: data.amount_total ? Number(data.amount_total) : integerAmount,
5066
+ reference: data.id,
5067
+ paymentUrl: data.url,
5068
+ rawResponse: data
5069
+ };
5070
+ }
5071
+ } catch (e) {
5072
+ return {
5073
+ success: false,
5074
+ provider: "stripe",
5075
+ orderId,
5076
+ amount: integerAmount,
5077
+ rawResponse: null,
5078
+ error: e.message || "Failed to make request to Stripe API"
5079
+ };
5080
+ }
5081
+ }
5082
+ async verifyCallback(body, config) {
5083
+ const webhookSecret = config.extra?.webhookSecret || config.secretKey || "";
5084
+ const signatureHeader = config.extra?.signatureHeader || "";
5085
+ const isValid = verifyStripeWebhook(body, signatureHeader, webhookSecret);
5086
+ const eventType = body.type || "";
5087
+ const obj = body.data?.object || body;
5088
+ const orderId = obj.metadata?.order_id || obj.client_reference_id || obj.id || "";
5089
+ const amount = obj.amount_total || obj.amount || 0;
5090
+ const paymentStatus = (obj.payment_status || obj.status || "").toLowerCase();
5091
+ const isPaid = eventType === "checkout.session.completed" && (paymentStatus === "paid" || paymentStatus === "complete") || eventType === "payment_intent.succeeded" && paymentStatus === "succeeded" || eventType === "charge.succeeded" && (paymentStatus === "succeeded" || paymentStatus === "paid") || paymentStatus === "paid" || paymentStatus === "succeeded";
5092
+ const isPending = paymentStatus === "unpaid" || paymentStatus === "processing" || paymentStatus === "requires_action";
5093
+ const isExpired = paymentStatus === "expired" || eventType === "checkout.session.expired";
5094
+ const isFailed = !isPaid && !isPending && !isExpired;
5095
+ const status = isPaid ? "paid" : isPending ? "pending" : isExpired ? "expired" : "failed";
5096
+ return {
5097
+ isValid,
5098
+ provider: "stripe",
5099
+ orderId: String(orderId),
5100
+ amount: Number(amount) || 0,
5101
+ status,
5102
+ isPaid,
5103
+ isPending,
5104
+ isFailed,
5105
+ isExpired,
5106
+ statusCode: eventType || paymentStatus,
5107
+ rawPayload: body
5108
+ };
5109
+ }
5110
+ async getPaymentMethods(params, config) {
5111
+ const staticMethods = [
5112
+ {
5113
+ paymentMethod: "credit_card",
5114
+ code: "credit_card",
5115
+ paymentName: "Credit / Debit Card (Visa, Mastercard, JCB, Amex)",
5116
+ paymentImage: "https://stripe.com/img/v3/home/social.png",
5117
+ totalFee: "2.9% + IDR 2,000",
5118
+ category: "Kartu Kredit"
5119
+ },
5120
+ {
5121
+ paymentMethod: "qris",
5122
+ code: "qris",
5123
+ paymentName: "QRIS (Indonesia)",
5124
+ paymentImage: "https://stripe.com/img/v3/home/social.png",
5125
+ totalFee: "0.7%",
5126
+ category: "QRIS"
5127
+ },
5128
+ {
5129
+ paymentMethod: "bca_va",
5130
+ code: "bca_va",
5131
+ paymentName: "BCA Virtual Account (Bank Transfer)",
5132
+ paymentImage: "https://stripe.com/img/v3/home/social.png",
5133
+ totalFee: "IDR 4,000",
5134
+ category: "Virtual Account"
5135
+ },
5136
+ {
5137
+ paymentMethod: "mandiri_va",
5138
+ code: "mandiri_va",
5139
+ paymentName: "Mandiri Virtual Account (Bank Transfer)",
5140
+ paymentImage: "https://stripe.com/img/v3/home/social.png",
5141
+ totalFee: "IDR 4,000",
5142
+ category: "Virtual Account"
5143
+ },
5144
+ {
5145
+ paymentMethod: "bni_va",
5146
+ code: "bni_va",
5147
+ paymentName: "BNI Virtual Account (Bank Transfer)",
5148
+ paymentImage: "https://stripe.com/img/v3/home/social.png",
5149
+ totalFee: "IDR 4,000",
5150
+ category: "Virtual Account"
5151
+ },
5152
+ {
5153
+ paymentMethod: "bri_va",
5154
+ code: "bri_va",
5155
+ paymentName: "BRI Virtual Account (Bank Transfer)",
5156
+ paymentImage: "https://stripe.com/img/v3/home/social.png",
5157
+ totalFee: "IDR 4,000",
5158
+ category: "Virtual Account"
5159
+ },
5160
+ {
5161
+ paymentMethod: "permata_va",
5162
+ code: "permata_va",
5163
+ paymentName: "Permata Virtual Account (Bank Transfer)",
5164
+ paymentImage: "https://stripe.com/img/v3/home/social.png",
5165
+ totalFee: "IDR 4,000",
5166
+ category: "Virtual Account"
5167
+ }
5168
+ ];
5169
+ const categories = {};
5170
+ for (const item of staticMethods) {
5171
+ if (!categories[item.category]) {
5172
+ categories[item.category] = [];
5173
+ }
5174
+ categories[item.category].push(item);
5175
+ }
5176
+ return {
5177
+ success: true,
5178
+ provider: "stripe",
5179
+ methods: staticMethods,
5180
+ categories,
5181
+ rawResponse: staticMethods
5182
+ };
5183
+ }
5184
+ async checkTransaction(params, config) {
5185
+ const { merchantOrderId } = params;
5186
+ const secretKey = config.apiKey || config.serverKey || config.secretKey || "";
5187
+ const baseUrl = this.getBaseUrl();
5188
+ let endpoint = `/checkout/sessions/${encodeURIComponent(merchantOrderId)}`;
5189
+ if (merchantOrderId.startsWith("pi_")) {
5190
+ endpoint = `/payment_intents/${encodeURIComponent(merchantOrderId)}`;
5191
+ }
5192
+ const url = `${baseUrl}${endpoint}`;
5193
+ const headers = {
5194
+ "Authorization": `Bearer ${secretKey}`,
5195
+ "Accept": "application/json"
5196
+ };
5197
+ try {
5198
+ const response = await fetch(url, {
5199
+ method: "GET",
5200
+ headers
5201
+ });
5202
+ const text = await response.text();
5203
+ let data = null;
5204
+ try {
5205
+ data = JSON.parse(text);
5206
+ } catch (e) {
5207
+ }
5208
+ if (!response.ok || !data || data.error) {
5209
+ return {
5210
+ success: false,
5211
+ provider: "stripe",
5212
+ orderId: merchantOrderId,
5213
+ reference: "",
5214
+ amount: 0,
5215
+ statusCode: response.status.toString(),
5216
+ status: "failed",
5217
+ isPaid: false,
5218
+ isPending: false,
5219
+ isFailed: true,
5220
+ isExpired: false,
5221
+ statusMessage: data?.error?.message || `HTTP error! Status: ${response.status}`,
5222
+ error: data?.error?.message || `HTTP error! Status: ${response.status}`,
5223
+ rawResponse: data
5224
+ };
5225
+ }
5226
+ const paymentStatus = (data.payment_status || data.status || "").toLowerCase();
5227
+ const isPaid = paymentStatus === "paid" || paymentStatus === "succeeded" || paymentStatus === "complete";
5228
+ const isPending = paymentStatus === "unpaid" || paymentStatus === "processing" || paymentStatus === "requires_action";
5229
+ const isExpired = paymentStatus === "expired";
5230
+ const isFailed = !isPaid && !isPending && !isExpired;
5231
+ const status = isPaid ? "paid" : isPending ? "pending" : isExpired ? "expired" : "failed";
5232
+ return {
5233
+ success: true,
5234
+ provider: "stripe",
5235
+ orderId: data.metadata?.order_id || data.client_reference_id || data.id || merchantOrderId,
5236
+ reference: data.id || "",
5237
+ amount: data.amount_total ? Number(data.amount_total) : data.amount ? Number(data.amount) : 0,
5238
+ statusCode: paymentStatus,
5239
+ status,
5240
+ isPaid,
5241
+ isPending,
5242
+ isFailed,
5243
+ isExpired,
5244
+ statusMessage: paymentStatus,
5245
+ paymentType: data.payment_method_types?.[0] || "card",
5246
+ transactionTime: data.created ? new Date(data.created * 1e3) : void 0,
5247
+ rawResponse: data
5248
+ };
5249
+ } catch (e) {
5250
+ return {
5251
+ success: false,
5252
+ provider: "stripe",
5253
+ orderId: merchantOrderId,
5254
+ reference: "",
5255
+ amount: 0,
5256
+ statusCode: "ERROR",
5257
+ status: "failed",
5258
+ isPaid: false,
5259
+ isPending: false,
5260
+ isFailed: true,
5261
+ isExpired: false,
5262
+ statusMessage: e.message || "Failed to check transaction status in Stripe",
5263
+ error: e.message || "Failed to check transaction status in Stripe",
5264
+ rawResponse: null
5265
+ };
5266
+ }
5267
+ }
5268
+ };
5269
+
4889
5270
  // src/clients/duitku.ts
4890
5271
  var DuitkuClient = class {
4891
5272
  merchantCode;
@@ -5581,6 +5962,76 @@ var OyClient = class {
5581
5962
  }
5582
5963
  };
5583
5964
 
5965
+ // src/clients/stripe.ts
5966
+ var StripeClient = class {
5967
+ secretKey;
5968
+ constructor(config) {
5969
+ this.secretKey = config.apiKey || config.serverKey || config.secretKey || "";
5970
+ }
5971
+ getBaseUrl() {
5972
+ return "https://api.stripe.com/v1";
5973
+ }
5974
+ /**
5975
+ * Helper HTTP Request ke Stripe API
5976
+ */
5977
+ async request(method, endpoint, body) {
5978
+ const url = `${this.getBaseUrl()}${endpoint}`;
5979
+ const headers = {
5980
+ "Authorization": `Bearer ${this.secretKey}`,
5981
+ "Accept": "application/json"
5982
+ };
5983
+ const fetchOptions = {
5984
+ method,
5985
+ headers
5986
+ };
5987
+ if (method === "POST" && body) {
5988
+ headers["Content-Type"] = "application/x-www-form-urlencoded";
5989
+ fetchOptions.body = serializeStripeParams(body);
5990
+ }
5991
+ const response = await fetch(url, fetchOptions);
5992
+ const text = await response.text();
5993
+ let data = null;
5994
+ try {
5995
+ data = JSON.parse(text);
5996
+ } catch (e) {
5997
+ }
5998
+ if (!response.ok || data?.error) {
5999
+ throw new Error(data?.error?.message || `HTTP error! Status: ${response.status} - ${text}`);
6000
+ }
6001
+ return data;
6002
+ }
6003
+ /**
6004
+ * Ambil detail Checkout Session
6005
+ */
6006
+ async retrieveCheckoutSession(sessionId) {
6007
+ return this.request("GET", `/checkout/sessions/${encodeURIComponent(sessionId)}`);
6008
+ }
6009
+ /**
6010
+ * Ambil detail Payment Intent
6011
+ */
6012
+ async retrievePaymentIntent(paymentIntentId) {
6013
+ return this.request("GET", `/payment_intents/${encodeURIComponent(paymentIntentId)}`);
6014
+ }
6015
+ /**
6016
+ * Cek saldo akun Stripe (Balance)
6017
+ */
6018
+ async checkBalance() {
6019
+ return this.request("GET", "/balance");
6020
+ }
6021
+ /**
6022
+ * Buat refund dana
6023
+ */
6024
+ async createRefund(paymentIntentId, amount) {
6025
+ const payload = {
6026
+ payment_intent: paymentIntentId
6027
+ };
6028
+ if (amount) {
6029
+ payload.amount = Math.round(amount);
6030
+ }
6031
+ return this.request("POST", "/refunds", payload);
6032
+ }
6033
+ };
6034
+
5584
6035
  // src/core/manager.ts
5585
6036
  var PaymentManager = class {
5586
6037
  providers = /* @__PURE__ */ new Map();
@@ -5595,6 +6046,7 @@ var PaymentManager = class {
5595
6046
  this.registerProvider(new FinpayProvider());
5596
6047
  this.registerProvider(new NicepayProvider());
5597
6048
  this.registerProvider(new OyProvider());
6049
+ this.registerProvider(new StripeProvider());
5598
6050
  }
5599
6051
  registerProvider(provider) {
5600
6052
  this.providers.set(provider.name.toLowerCase(), provider);
@@ -5666,6 +6118,12 @@ var PaymentManager = class {
5666
6118
  getOyClient(config) {
5667
6119
  return new OyClient(config);
5668
6120
  }
6121
+ getStripeProvider() {
6122
+ return this.getProvider("stripe");
6123
+ }
6124
+ getStripeClient(config) {
6125
+ return new StripeClient(config);
6126
+ }
5669
6127
  async createInvoice(providerName, params, config) {
5670
6128
  const provider = this.getProvider(providerName);
5671
6129
  return provider.createInvoice(params, config);
@@ -5723,6 +6181,8 @@ function resolveConfigFromEnv(customConfig) {
5723
6181
  sandbox = env.NICEPAY_SANDBOX === "true" || env.NICEPAY_SANDBOX === "1";
5724
6182
  } else if (env.OY_SANDBOX !== void 0) {
5725
6183
  sandbox = env.OY_SANDBOX === "true" || env.OY_SANDBOX === "1";
6184
+ } else if (env.STRIPE_SANDBOX !== void 0) {
6185
+ sandbox = env.STRIPE_SANDBOX === "true" || env.STRIPE_SANDBOX === "1";
5726
6186
  } else {
5727
6187
  sandbox = env.NODE_ENV !== "production";
5728
6188
  }
@@ -5748,6 +6208,8 @@ function resolveConfigFromEnv(customConfig) {
5748
6208
  apiKey = env.NICEPAY_KEY || env.NICEPAY_MERCHANT_KEY || env.NICEPAY_SECRET_KEY || env.NICEPAY_API_KEY || env.BUAYAR_API_KEY || env.PG_API_KEY || env.PAYMENT_API_KEY;
5749
6209
  } else if (provider === "oy" || provider === "oyindonesia") {
5750
6210
  apiKey = env.OY_API_KEY || env.BUAYAR_API_KEY || env.PG_API_KEY || env.PAYMENT_API_KEY;
6211
+ } else if (provider === "stripe") {
6212
+ apiKey = env.STRIPE_SECRET_KEY || env.STRIPE_KEY || env.BUAYAR_API_KEY || env.PG_API_KEY || env.PAYMENT_API_KEY;
5751
6213
  } else {
5752
6214
  apiKey = env.BUAYAR_API_KEY || env.PG_API_KEY || env.PAYMENT_API_KEY || env.PG_SECRET_KEY || env.BUAYAR_SECRET_KEY;
5753
6215
  }
@@ -5782,17 +6244,21 @@ function resolveConfigFromEnv(customConfig) {
5782
6244
  } else if (provider === "oy" || provider === "oyindonesia") {
5783
6245
  merchantCode = merchantCode || env.OY_USERNAME || env.BUAYAR_MERCHANT_CODE || env.PG_MERCHANT_CODE || env.PAYMENT_MERCHANT_CODE;
5784
6246
  clientKey = clientKey || env.OY_USERNAME || env.BUAYAR_CLIENT_KEY;
6247
+ } else if (provider === "stripe") {
6248
+ clientKey = clientKey || env.STRIPE_PUBLIC_KEY || env.STRIPE_PUBLISHABLE_KEY || env.BUAYAR_CLIENT_KEY || env.BUAYAR_PUBLIC_KEY;
6249
+ merchantCode = merchantCode || clientKey || "stripe";
5785
6250
  } else {
5786
6251
  merchantCode = merchantCode || env.BUAYAR_MERCHANT_CODE || env.PG_MERCHANT_CODE || env.PAYMENT_MERCHANT_CODE;
5787
6252
  }
5788
6253
  const projectId = customConfig?.projectId || env.BUAYAR_PROJECT_ID || env.PG_PROJECT_ID || env.PROJECT_ID;
5789
- const publicKey = customConfig?.publicKey || env.BUAYAR_PUBLIC_KEY || env.PG_PUBLIC_KEY || env.PUBLIC_KEY;
6254
+ const publicKey = customConfig?.publicKey || env.BUAYAR_PUBLIC_KEY || env.PG_PUBLIC_KEY || env.PUBLIC_KEY || env.STRIPE_PUBLIC_KEY || env.STRIPE_PUBLISHABLE_KEY;
5790
6255
  const privateKey = customConfig?.privateKey || env.BUAYAR_PRIVATE_KEY || env.PG_PRIVATE_KEY || env.PRIVATE_KEY;
5791
- const secretKey = customConfig?.secretKey || env.BUAYAR_SECRET_KEY || env.PG_SECRET_KEY || env.SECRET_KEY || env.XENDIT_SECRET_KEY || env.DOKU_SECRET_KEY || env.PRISMALINK_SECRET_KEY || env.FASPAY_PASSWORD || env.FINPAY_MERCHANT_KEY || env.NICEPAY_KEY || env.OY_API_KEY;
6256
+ const secretKey = customConfig?.secretKey || env.BUAYAR_SECRET_KEY || env.PG_SECRET_KEY || env.SECRET_KEY || env.XENDIT_SECRET_KEY || env.DOKU_SECRET_KEY || env.PRISMALINK_SECRET_KEY || env.FASPAY_PASSWORD || env.FINPAY_MERCHANT_KEY || env.NICEPAY_KEY || env.OY_API_KEY || env.STRIPE_SECRET_KEY;
5792
6257
  const callbackUrl = customConfig?.callbackUrl || env.BUAYAR_CALLBACK_URL || env.PG_CALLBACK_URL || env.PAYMENT_CALLBACK_URL;
5793
6258
  const returnUrl = customConfig?.returnUrl || env.BUAYAR_RETURN_URL || env.PG_RETURN_URL || env.PAYMENT_RETURN_URL;
5794
6259
  const extra = {
5795
6260
  webhookToken: env.XENDIT_WEBHOOK_TOKEN || env.BUAYAR_WEBHOOK_TOKEN,
6261
+ webhookSecret: env.STRIPE_WEBHOOK_SECRET || env.BUAYAR_WEBHOOK_SECRET,
5796
6262
  merchantName: env.FASPAY_MERCHANT_NAME || env.BUAYAR_MERCHANT_NAME,
5797
6263
  userId: env.FASPAY_USER_ID,
5798
6264
  iMid: env.NICEPAY_IMID,
@@ -5838,7 +6304,7 @@ var Buayar = class {
5838
6304
  this.config = resolveConfigFromEnv({ ...this.config, ...config });
5839
6305
  }
5840
6306
  /**
5841
- * Dapatkan nama provider aktif ('midtrans' | 'duitku' | 'ipaymu' | 'xendit' | 'doku' | 'prismalink' | 'faspay' | 'finpay' | 'nicepay' | 'oy' | ...)
6307
+ * Dapatkan nama provider aktif ('midtrans' | 'duitku' | 'ipaymu' | 'xendit' | 'doku' | 'prismalink' | 'faspay' | 'finpay' | 'nicepay' | 'oy' | 'stripe' | ...)
5842
6308
  */
5843
6309
  get provider() {
5844
6310
  return this.config.provider || "midtrans";
@@ -5886,6 +6352,13 @@ var Buayar = class {
5886
6352
  */
5887
6353
  async verifyWebhook(payload, headers, configOverride) {
5888
6354
  const mergedConfig = { ...this.config, ...configOverride };
6355
+ if (headers) {
6356
+ const sigHeader = headers["stripe-signature"] || headers["Stripe-Signature"];
6357
+ if (sigHeader) {
6358
+ if (!mergedConfig.extra) mergedConfig.extra = {};
6359
+ mergedConfig.extra.signatureHeader = Array.isArray(sigHeader) ? sigHeader[0] : sigHeader;
6360
+ }
6361
+ }
5889
6362
  let providerName = configOverride?.provider || this.provider;
5890
6363
  if (payload) {
5891
6364
  if (payload.signature_key && payload.transaction_status) {
@@ -5906,6 +6379,8 @@ var Buayar = class {
5906
6379
  providerName = "oy";
5907
6380
  } else if (payload.merchant_id && payload.order_id && payload.signature) {
5908
6381
  providerName = "prismalink";
6382
+ } else if (payload.object === "event" || payload.type && payload.data?.object && payload.api_version) {
6383
+ providerName = "stripe";
5909
6384
  } else if (payload.external_id || payload.event?.startsWith("payment.") || payload.event?.startsWith("qr.") || payload.data?.reference_id) {
5910
6385
  providerName = "xendit";
5911
6386
  }
@@ -5975,6 +6450,12 @@ var Buayar = class {
5975
6450
  ...configOverride
5976
6451
  });
5977
6452
  }
6453
+ getStripeClient(configOverride) {
6454
+ return new StripeClient({
6455
+ ...this.config,
6456
+ ...configOverride
6457
+ });
6458
+ }
5978
6459
  };
5979
6460
  var buayar = new Buayar();
5980
6461
  export {
@@ -5989,6 +6470,7 @@ export {
5989
6470
  CANONICAL_TO_NICEPAY,
5990
6471
  CANONICAL_TO_OY,
5991
6472
  CANONICAL_TO_PRISMALINK,
6473
+ CANONICAL_TO_STRIPE,
5992
6474
  CANONICAL_TO_XENDIT,
5993
6475
  CORE_API_METHODS,
5994
6476
  DUITKU_TO_CANONICAL,
@@ -6013,6 +6495,8 @@ export {
6013
6495
  PaymentManager,
6014
6496
  PrismalinkClient,
6015
6497
  PrismalinkProvider,
6498
+ StripeClient,
6499
+ StripeProvider,
6016
6500
  XenditClient,
6017
6501
  XenditProvider,
6018
6502
  buayar,
@@ -6036,6 +6520,7 @@ export {
6036
6520
  paymentManager,
6037
6521
  resolveConfigFromEnv,
6038
6522
  safeCompare,
6523
+ serializeStripeParams,
6039
6524
  sha256,
6040
6525
  sha512,
6041
6526
  toCanonicalPaymentMethod,
@@ -6047,6 +6532,7 @@ export {
6047
6532
  toNicepayPaymentMethod,
6048
6533
  toOyPaymentMethod,
6049
6534
  toPrismalinkPaymentMethod,
6535
+ toStripePaymentMethod,
6050
6536
  toXenditPaymentMethod,
6051
6537
  verifyDokuWebhookSignature,
6052
6538
  verifyDuitkuCallbackSignature,
@@ -6056,5 +6542,6 @@ export {
6056
6542
  verifyNicepayWebhook,
6057
6543
  verifyOyWebhook,
6058
6544
  verifyPrismalinkSignature,
6545
+ verifyStripeWebhook,
6059
6546
  verifyXenditWebhookToken
6060
6547
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crediblemark/buayar",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Unified Payment Gateway SDK for Node.js and TypeScript supporting multiple providers",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",