@crediblemark/buayar 0.8.0 → 0.8.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.js CHANGED
@@ -1715,8 +1715,8 @@ var MidtransProvider = class extends BasePaymentProvider {
1715
1715
  // src/providers/ipaymu/signature.ts
1716
1716
  function generateIpaymuSignature(method, va, apiKey, body) {
1717
1717
  const timestamp = Date.now().toString();
1718
- const bodyString = body ? typeof body === "string" ? body : JSON.stringify(body) : "";
1719
- const bodyHash = body ? sha256(bodyString).toLowerCase() : "";
1718
+ const bodyString = body ? typeof body === "string" ? body : JSON.stringify(body) : "{}";
1719
+ const bodyHash = sha256(bodyString).toLowerCase();
1720
1720
  const stringToSign = `${method.toUpperCase()}:${va}:${bodyHash}:${apiKey}`;
1721
1721
  const signature = hmacSha256(stringToSign, apiKey);
1722
1722
  return { signature, timestamp };
@@ -1751,6 +1751,7 @@ var IpaymuProvider = class extends BasePaymentProvider {
1751
1751
  const redirectUrl = returnUrl || config.returnUrl || "https://localhost/return";
1752
1752
  const feeDirection = params.feeDirection || params.extra?.feeDirection || config.extra?.feeDirection;
1753
1753
  const escrow = params.escrow !== void 0 ? params.escrow : params.extra?.escrow !== void 0 ? params.extra?.escrow : config.extra?.escrow;
1754
+ const subAccount = params.subAccountId || params.extra?.subAccountId || params.extra?.account || params.extra?.childAccount || params.account || config.extra?.account;
1754
1755
  let payload;
1755
1756
  if (isDirect) {
1756
1757
  payload = {
@@ -1767,6 +1768,7 @@ var IpaymuProvider = class extends BasePaymentProvider {
1767
1768
  ...ipaymuMethod.paymentChannel ? { paymentChannel: ipaymuMethod.paymentChannel } : {},
1768
1769
  ...feeDirection ? { feeDirection } : {},
1769
1770
  ...escrow !== void 0 ? { escrow } : {},
1771
+ ...subAccount ? { account: subAccount } : {},
1770
1772
  ...params.providerParams
1771
1773
  };
1772
1774
  } else {
@@ -1789,6 +1791,7 @@ var IpaymuProvider = class extends BasePaymentProvider {
1789
1791
  buyerPhone: customer.phone || "081234567890",
1790
1792
  ...feeDirection ? { feeDirection } : {},
1791
1793
  ...escrow !== void 0 ? { escrow } : {},
1794
+ ...subAccount ? { account: subAccount } : {},
1792
1795
  ...params.providerParams
1793
1796
  };
1794
1797
  }
@@ -1891,221 +1894,106 @@ var IpaymuProvider = class extends BasePaymentProvider {
1891
1894
  const va = config.merchantCode || config.merchantId || "";
1892
1895
  const apiKey = config.apiKey || "";
1893
1896
  const sandbox = !!config.sandbox;
1894
- if (va && apiKey) {
1895
- try {
1896
- const url = `${this.getBaseUrl(sandbox)}/payment-method-list`;
1897
- const payload = { account: va };
1898
- const { signature, timestamp } = generateIpaymuSignature("POST", va, apiKey, payload);
1899
- const response = await fetch(url, {
1900
- method: "POST",
1901
- headers: {
1902
- "Content-Type": "application/json",
1903
- "Accept": "application/json",
1904
- "va": va,
1905
- "signature": signature,
1906
- "timestamp": timestamp
1907
- },
1908
- body: JSON.stringify(payload)
1909
- });
1910
- const data = await response.json().catch(() => null);
1911
- if (response.ok && data?.Data && Array.isArray(data.Data)) {
1912
- const methods = [];
1913
- const categories2 = {};
1914
- for (const group of data.Data) {
1915
- const groupCode = (group.Code || "").toLowerCase();
1916
- const groupName = group.Name || group.Description || "Lainnya";
1917
- const channels = group.Channels || [];
1918
- let category = "Lainnya";
1919
- if (groupCode === "va") category = "Virtual Account";
1920
- else if (groupCode === "cstore") category = "Retail / Gerai";
1921
- else if (groupCode === "qris") category = "QRIS";
1922
- else if (groupCode === "cc") category = "Kartu Kredit";
1923
- else if (groupCode === "paylater") category = "Paylater / Cicilan";
1924
- else if (groupCode === "cod") category = "COD";
1925
- else category = groupName;
1926
- for (const ch of channels) {
1927
- const chCode = (ch.Code || "").toLowerCase();
1928
- let canonicalCode = chCode;
1929
- if (groupCode === "va") {
1930
- canonicalCode = chCode === "bag" ? "bag_va" : chCode === "bmi" ? "muamalat_va" : `${chCode}_va`;
1931
- } else if (groupCode === "cc") {
1932
- canonicalCode = "credit_card";
1933
- }
1934
- let totalFee = "-";
1935
- if (ch.TransactionFee) {
1936
- if (ch.TransactionFee.ActualFeeType === "PERCENT") {
1937
- totalFee = `${ch.TransactionFee.ActualFee}%`;
1938
- } else if (ch.TransactionFee.ActualFee !== void 0) {
1939
- totalFee = `IDR ${Number(ch.TransactionFee.ActualFee).toLocaleString()}`;
1940
- }
1897
+ if (!va || !apiKey) {
1898
+ return {
1899
+ success: false,
1900
+ provider: "ipaymu",
1901
+ methods: [],
1902
+ categories: {},
1903
+ error: "Missing iPaymu credentials (BUAYAR_MERCHANT_CODE/VA or BUAYAR_API_KEY)",
1904
+ rawResponse: null
1905
+ };
1906
+ }
1907
+ try {
1908
+ const url = `${this.getBaseUrl(sandbox)}/payment-channels`;
1909
+ const { signature, timestamp } = generateIpaymuSignature("GET", va, apiKey);
1910
+ const response = await fetch(url, {
1911
+ method: "GET",
1912
+ headers: {
1913
+ "Content-Type": "application/json",
1914
+ "Accept": "application/json",
1915
+ "va": va,
1916
+ "signature": signature,
1917
+ "timestamp": timestamp
1918
+ }
1919
+ });
1920
+ const data = await response.json().catch(() => null);
1921
+ if (response.ok && data?.Data && Array.isArray(data.Data)) {
1922
+ const methods = [];
1923
+ const categories = {};
1924
+ for (const group of data.Data) {
1925
+ const groupCode = (group.Code || "").toLowerCase();
1926
+ const groupName = group.Name || group.Description || "Lainnya";
1927
+ const channels = group.Channels || [];
1928
+ let category = "Lainnya";
1929
+ if (groupCode === "va") category = "Virtual Account";
1930
+ else if (groupCode === "cstore") category = "Retail / Gerai";
1931
+ else if (groupCode === "qris") category = "QRIS";
1932
+ else if (groupCode === "cc") category = "Kartu Kredit";
1933
+ else if (groupCode === "paylater") category = "Paylater / Cicilan";
1934
+ else if (groupCode === "cod") category = "COD";
1935
+ else category = groupName;
1936
+ for (const ch of channels) {
1937
+ const chCode = (ch.Code || "").toLowerCase();
1938
+ let canonicalCode = chCode;
1939
+ if (groupCode === "va") {
1940
+ canonicalCode = chCode === "bag" ? "bag_va" : chCode === "bmi" ? "muamalat_va" : `${chCode}_va`;
1941
+ } else if (groupCode === "cc") {
1942
+ canonicalCode = "credit_card";
1943
+ }
1944
+ let totalFee = "-";
1945
+ if (ch.TransactionFee) {
1946
+ if (ch.TransactionFee.ActualFeeType === "PERCENT") {
1947
+ totalFee = `${ch.TransactionFee.ActualFee}%`;
1948
+ } else if (ch.TransactionFee.ActualFee !== void 0) {
1949
+ totalFee = `IDR ${Number(ch.TransactionFee.ActualFee).toLocaleString()}`;
1941
1950
  }
1942
- const pm = {
1943
- paymentMethod: canonicalCode,
1944
- code: canonicalCode,
1945
- paymentName: ch.Name || ch.Description || canonicalCode,
1946
- paymentImage: `https://my.ipaymu.com/images/banks/${chCode}.png`,
1947
- totalFee,
1948
- category,
1949
- extra: {
1950
- healthStatus: ch.HealthStatus,
1951
- instructionsDoc: ch.PaymentInstructionsDoc,
1952
- feeDetail: ch.TransactionFee
1953
- }
1954
- };
1955
- methods.push(pm);
1956
- if (!categories2[category]) categories2[category] = [];
1957
- categories2[category].push(pm);
1958
1951
  }
1959
- }
1960
- if (methods.length > 0) {
1961
- return {
1962
- success: true,
1963
- provider: "ipaymu",
1964
- methods,
1965
- categories: categories2,
1966
- rawResponse: data
1952
+ const pm = {
1953
+ paymentMethod: canonicalCode,
1954
+ code: canonicalCode,
1955
+ paymentName: ch.Name || ch.Description || canonicalCode,
1956
+ paymentImage: ch.Logo || `https://my.ipaymu.com/images/banks/${chCode}.png`,
1957
+ totalFee,
1958
+ category,
1959
+ extra: {
1960
+ healthStatus: ch.HealthStatus,
1961
+ featureStatus: ch.FeatureStatus,
1962
+ instructionsDoc: ch.PaymentInstructionsDoc,
1963
+ feeDetail: ch.TransactionFee
1964
+ }
1967
1965
  };
1966
+ methods.push(pm);
1967
+ if (!categories[category]) categories[category] = [];
1968
+ categories[category].push(pm);
1968
1969
  }
1969
1970
  }
1970
- } catch (err) {
1971
- }
1972
- }
1973
- const staticMethods = [
1974
- {
1975
- paymentMethod: "bca_va",
1976
- code: "bca_va",
1977
- paymentName: "BCA Virtual Account",
1978
- paymentImage: "https://my.ipaymu.com/images/banks/bca.png",
1979
- totalFee: "IDR 3,500",
1980
- category: "Virtual Account"
1981
- },
1982
- {
1983
- paymentMethod: "mandiri_va",
1984
- code: "mandiri_va",
1985
- paymentName: "Mandiri Virtual Account",
1986
- paymentImage: "https://my.ipaymu.com/images/banks/mandiri.png",
1987
- totalFee: "IDR 3,500",
1988
- category: "Virtual Account"
1989
- },
1990
- {
1991
- paymentMethod: "bni_va",
1992
- code: "bni_va",
1993
- paymentName: "BNI Virtual Account",
1994
- paymentImage: "https://my.ipaymu.com/images/banks/bni.png",
1995
- totalFee: "IDR 3,500",
1996
- category: "Virtual Account"
1997
- },
1998
- {
1999
- paymentMethod: "bri_va",
2000
- code: "bri_va",
2001
- paymentName: "BRI Virtual Account",
2002
- paymentImage: "https://my.ipaymu.com/images/banks/bri.png",
2003
- totalFee: "IDR 3,500",
2004
- category: "Virtual Account"
2005
- },
2006
- {
2007
- paymentMethod: "cimb_va",
2008
- code: "cimb_va",
2009
- paymentName: "CIMB Niaga Virtual Account",
2010
- paymentImage: "https://my.ipaymu.com/images/banks/cimb.png",
2011
- totalFee: "IDR 3,500",
2012
- category: "Virtual Account"
2013
- },
2014
- {
2015
- paymentMethod: "permata_va",
2016
- code: "permata_va",
2017
- paymentName: "Permata Virtual Account",
2018
- paymentImage: "https://my.ipaymu.com/images/banks/permata.png",
2019
- totalFee: "IDR 3,500",
2020
- category: "Virtual Account"
2021
- },
2022
- {
2023
- paymentMethod: "danamon_va",
2024
- code: "danamon_va",
2025
- paymentName: "Danamon Virtual Account",
2026
- paymentImage: "https://my.ipaymu.com/images/banks/danamon.png",
2027
- totalFee: "IDR 3,500",
2028
- category: "Virtual Account"
2029
- },
2030
- {
2031
- paymentMethod: "bsi_va",
2032
- code: "bsi_va",
2033
- paymentName: "BSI Virtual Account",
2034
- paymentImage: "https://my.ipaymu.com/images/banks/bsi.png",
2035
- totalFee: "IDR 3,500",
2036
- category: "Virtual Account"
2037
- },
2038
- {
2039
- paymentMethod: "bag_va",
2040
- code: "bag_va",
2041
- paymentName: "Bank Artha Graha Virtual Account",
2042
- paymentImage: "https://my.ipaymu.com/images/banks/bag.png",
2043
- totalFee: "IDR 3,500",
2044
- category: "Virtual Account"
2045
- },
2046
- {
2047
- paymentMethod: "muamalat_va",
2048
- code: "muamalat_va",
2049
- paymentName: "Bank Muamalat Virtual Account",
2050
- paymentImage: "https://my.ipaymu.com/images/banks/bmi.png",
2051
- totalFee: "IDR 3,500",
2052
- category: "Virtual Account"
2053
- },
2054
- {
2055
- paymentMethod: "qris",
2056
- code: "qris",
2057
- paymentName: "QRIS (GoPay, ShopeePay, DANA, OVO, LinkAja)",
2058
- paymentImage: "https://my.ipaymu.com/images/banks/qris.png",
2059
- totalFee: "0.7%",
2060
- category: "QRIS"
2061
- },
2062
- {
2063
- paymentMethod: "alfamart",
2064
- code: "alfamart",
2065
- paymentName: "Alfamart",
2066
- paymentImage: "https://my.ipaymu.com/images/banks/alfamart.png",
2067
- totalFee: "IDR 5,000",
2068
- category: "Retail / Gerai"
2069
- },
2070
- {
2071
- paymentMethod: "indomaret",
2072
- code: "indomaret",
2073
- paymentName: "Indomaret",
2074
- paymentImage: "https://my.ipaymu.com/images/banks/indomaret.png",
2075
- totalFee: "IDR 5,000",
2076
- category: "Retail / Gerai"
2077
- },
2078
- {
2079
- paymentMethod: "credit_card",
2080
- code: "credit_card",
2081
- paymentName: "Credit / Debit Card (Visa, Mastercard)",
2082
- paymentImage: "https://my.ipaymu.com/images/banks/cc.png",
2083
- totalFee: "2.9% + IDR 2,000",
2084
- category: "Kartu Kredit"
2085
- },
2086
- {
2087
- paymentMethod: "akulaku",
2088
- code: "akulaku",
2089
- paymentName: "Akulaku Paylater",
2090
- paymentImage: "https://my.ipaymu.com/images/banks/akulaku.png",
2091
- totalFee: "1.7%",
2092
- category: "Paylater / Cicilan"
2093
- }
2094
- ];
2095
- const categories = {};
2096
- for (const item of staticMethods) {
2097
- if (!categories[item.category]) {
2098
- categories[item.category] = [];
1971
+ return {
1972
+ success: true,
1973
+ provider: "ipaymu",
1974
+ methods,
1975
+ categories,
1976
+ rawResponse: data
1977
+ };
2099
1978
  }
2100
- categories[item.category].push(item);
1979
+ return {
1980
+ success: false,
1981
+ provider: "ipaymu",
1982
+ methods: [],
1983
+ categories: {},
1984
+ error: data?.Message || data?.message || `Failed to fetch payment channels (HTTP ${response.status})`,
1985
+ rawResponse: data
1986
+ };
1987
+ } catch (err) {
1988
+ return {
1989
+ success: false,
1990
+ provider: "ipaymu",
1991
+ methods: [],
1992
+ categories: {},
1993
+ error: err.message || "Failed to fetch iPaymu payment channels",
1994
+ rawResponse: null
1995
+ };
2101
1996
  }
2102
- return {
2103
- success: true,
2104
- provider: "ipaymu",
2105
- methods: staticMethods,
2106
- categories,
2107
- rawResponse: staticMethods
2108
- };
2109
1997
  }
2110
1998
  async checkTransaction(params, config) {
2111
1999
  const { merchantOrderId } = params;
@@ -8376,13 +8264,19 @@ var IpaymuClient = class {
8376
8264
  return this.request("POST", "/transaction", { transactionId });
8377
8265
  }
8378
8266
  /**
8379
- * Ambil daftar channel pembayaran aktif milik merchant
8267
+ * Ambil daftar channel pembayaran aktif milik merchant (Official v2: GET /payment-channels)
8380
8268
  */
8381
8269
  async getPaymentMethods() {
8382
- return this.request("POST", "/payment-method-list", { account: this.va });
8270
+ return this.request("GET", "/payment-channels");
8383
8271
  }
8384
8272
  /**
8385
- * Ambil riwayat transaksi merchant berpaginasi
8273
+ * Alias untuk getPaymentMethods (Official v2)
8274
+ */
8275
+ async getPaymentChannels() {
8276
+ return this.request("GET", "/payment-channels");
8277
+ }
8278
+ /**
8279
+ * Ambil riwayat transaksi merchant berpaginasi (Official v2: POST /history)
8386
8280
  */
8387
8281
  async getHistory(params) {
8388
8282
  const payload = {
@@ -8394,42 +8288,111 @@ var IpaymuClient = class {
8394
8288
  return this.request("POST", "/history", payload);
8395
8289
  }
8396
8290
  /**
8397
- * Ambil daftar seluruh bank di Indonesia
8291
+ * Ambil daftar seluruh bank di Indonesia (Official v2: POST /banklist)
8398
8292
  */
8399
8293
  async getBankList() {
8400
8294
  return this.request("POST", "/banklist", { account: this.va });
8401
8295
  }
8402
8296
  /**
8403
- * Ambil jangkauan area pengiriman COD
8297
+ * Cari jangkauan area pengiriman COD (Official v2: GET /cod/area?area=keyword)
8404
8298
  */
8405
- async getCodArea(postalCode) {
8406
- const payload = { account: this.va };
8407
- if (postalCode) payload.postalCode = postalCode;
8408
- return this.request("POST", "/cod/getarea", payload);
8299
+ async getCodArea(area) {
8300
+ const query = { area };
8301
+ return this.request("GET", `/cod/area?area=${encodeURIComponent(area)}`, query);
8409
8302
  }
8410
8303
  /**
8411
- * Hitung tarif ongkir pengiriman COD
8304
+ * Hitung tarif ongkir pengiriman COD (Official v2: POST /cod/shipping-calculate)
8412
8305
  */
8413
8306
  async getCodRate(params) {
8414
- return this.request("POST", "/cod/getrate", { account: this.va, ...params });
8307
+ const { pickupArea, deliveryArea, ...rest } = params;
8308
+ const pickupId = params.pickup_area_id !== void 0 ? params.pickup_area_id : pickupArea;
8309
+ const destId = params.destination_area_id !== void 0 ? params.destination_area_id : deliveryArea;
8310
+ const payload = {
8311
+ ...rest,
8312
+ pickup_area_id: pickupId !== void 0 ? String(pickupId) : void 0,
8313
+ destination_area_id: destId !== void 0 ? String(destId) : void 0,
8314
+ amount: params.amount || 0
8315
+ };
8316
+ return this.request("POST", "/cod/shipping-calculate", payload);
8415
8317
  }
8416
8318
  /**
8417
- * Request pickup kurir COD
8319
+ * Request pickup kurir COD (Official v2: POST /cod/pickup)
8418
8320
  */
8419
8321
  async getCodPickup(params) {
8420
- return this.request("POST", "/cod/pickup", { account: this.va, ...params });
8322
+ const { transactionId, ...rest } = params;
8323
+ const payload = {
8324
+ ...rest,
8325
+ transaction_id: params.transaction_id || transactionId
8326
+ };
8327
+ return this.request("POST", "/cod/pickup", payload);
8421
8328
  }
8422
8329
  /**
8423
- * Ambil nomor resi / AWB pengiriman COD
8330
+ * Unduh label pengiriman / AWB COD (Official v2: GET /cod/download-label/:transaction_id)
8424
8331
  */
8425
8332
  async getCodAwb(transactionId) {
8426
- return this.request("POST", "/cod/getawb", { account: this.va, transactionId });
8333
+ return this.request("GET", `/cod/download-label/${transactionId}`);
8334
+ }
8335
+ /**
8336
+ * Lacak status pengiriman kurir COD berdasarkan no resi / AWB (Official v2: POST /cod/tracking)
8337
+ */
8338
+ async getCodTracking(params) {
8339
+ const payload = typeof params === "string" ? { awb: params } : {
8340
+ awb: params.awb,
8341
+ transaction_id: params.transaction_id || params.transactionId
8342
+ };
8343
+ return this.request("POST", "/cod/tracking", payload);
8344
+ }
8345
+ // ==========================================
8346
+ // Public Area Lookup API (docs.ipaymu.com/en/docs/area-api)
8347
+ // Read-only endpoint untuk provinsi, kota/kabupaten, kecamatan, dan kelurahan
8348
+ // ==========================================
8349
+ /**
8350
+ * Ambil daftar seluruh provinsi di Indonesia
8351
+ */
8352
+ async getAreasProvince() {
8353
+ const res = await fetch("https://my.ipaymu.com/api/areas/province");
8354
+ return res.json();
8427
8355
  }
8428
8356
  /**
8429
- * Lacak status pengiriman kurir berdasarkan no resi / AWB
8357
+ * Ambil daftar kota / kabupaten berdasarkan ID provinsi
8430
8358
  */
8431
- async getCodTracking(awb) {
8432
- return this.request("POST", "/cod/tracking", { account: this.va, awb });
8359
+ async getAreasCity(provinceId) {
8360
+ const res = await fetch(`https://my.ipaymu.com/api/areas/city/${provinceId}`);
8361
+ return res.json();
8362
+ }
8363
+ /**
8364
+ * Ambil daftar kecamatan berdasarkan ID kota / kabupaten
8365
+ */
8366
+ async getAreasDistrict(cityId) {
8367
+ const res = await fetch(`https://my.ipaymu.com/api/areas/district/${cityId}`);
8368
+ return res.json();
8369
+ }
8370
+ /**
8371
+ * Ambil daftar kelurahan berdasarkan ID kecamatan
8372
+ */
8373
+ async getAreasVillage(districtId) {
8374
+ const res = await fetch(`https://my.ipaymu.com/api/areas/village/${districtId}`);
8375
+ return res.json();
8376
+ }
8377
+ // ==========================================
8378
+ // Split Payment — Single Register API
8379
+ // https://ipaymu.com/en/split-payment/
8380
+ // ==========================================
8381
+ /**
8382
+ * Daftarkan agen / reseller / mitra baru untuk Split Payment (Single Register API: POST /api/v2/register)
8383
+ * Mengembalikan VA child account yang siap digunakan untuk parameter `subAccountId` saat membuat transaksi.
8384
+ */
8385
+ async registerUser(params) {
8386
+ const { name, email, phone, password, ...rest } = params;
8387
+ const payload = {
8388
+ ...rest,
8389
+ account: this.va,
8390
+ name,
8391
+ email,
8392
+ phone,
8393
+ password: password || "Password123!"
8394
+ };
8395
+ return this.request("POST", "/register", payload);
8433
8396
  }
8434
8397
  };
8435
8398