@crediblemark/buayar 0.7.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/README.md +74 -75
- package/dist/cli/index.js +1 -1
- package/dist/index.d.mts +139 -4
- package/dist/index.d.ts +139 -4
- package/dist/index.js +273 -137
- package/dist/index.mjs +273 -137
- package/docs/guide.md +53 -50
- package/docs/ipaymu.md +295 -0
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -123,6 +123,9 @@ var CANONICAL_TO_IPAYMU = {
|
|
|
123
123
|
permata_va: { paymentMethod: "va", paymentChannel: "permata" },
|
|
124
124
|
danamon_va: { paymentMethod: "va", paymentChannel: "danamon" },
|
|
125
125
|
bsi_va: { paymentMethod: "va", paymentChannel: "bsi" },
|
|
126
|
+
bag_va: { paymentMethod: "va", paymentChannel: "bag" },
|
|
127
|
+
muamalat_va: { paymentMethod: "va", paymentChannel: "bmi" },
|
|
128
|
+
bmi_va: { paymentMethod: "va", paymentChannel: "bmi" },
|
|
126
129
|
qris: { paymentMethod: "qris", paymentChannel: "mpm" },
|
|
127
130
|
gopay_qris: { paymentMethod: "qris", paymentChannel: "mpm" },
|
|
128
131
|
shopeepay_qris: { paymentMethod: "qris", paymentChannel: "mpm" },
|
|
@@ -1548,8 +1551,8 @@ var MidtransProvider = class extends BasePaymentProvider {
|
|
|
1548
1551
|
// src/providers/ipaymu/signature.ts
|
|
1549
1552
|
function generateIpaymuSignature(method, va, apiKey, body) {
|
|
1550
1553
|
const timestamp = Date.now().toString();
|
|
1551
|
-
const bodyString = body ? typeof body === "string" ? body : JSON.stringify(body) : "";
|
|
1552
|
-
const bodyHash =
|
|
1554
|
+
const bodyString = body ? typeof body === "string" ? body : JSON.stringify(body) : "{}";
|
|
1555
|
+
const bodyHash = sha256(bodyString).toLowerCase();
|
|
1553
1556
|
const stringToSign = `${method.toUpperCase()}:${va}:${bodyHash}:${apiKey}`;
|
|
1554
1557
|
const signature = hmacSha256(stringToSign, apiKey);
|
|
1555
1558
|
return { signature, timestamp };
|
|
@@ -1580,35 +1583,51 @@ var IpaymuProvider = class extends BasePaymentProvider {
|
|
|
1580
1583
|
const baseUrl = this.getBaseUrl(sandbox);
|
|
1581
1584
|
const endpoint = isDirect ? "/payment/direct" : "/payment";
|
|
1582
1585
|
const url = `${baseUrl}${endpoint}`;
|
|
1586
|
+
const notifyUrl = callbackUrl || config.callbackUrl || "https://localhost/callback";
|
|
1587
|
+
const redirectUrl = returnUrl || config.returnUrl || "https://localhost/return";
|
|
1588
|
+
const feeDirection = params.feeDirection || params.extra?.feeDirection || config.extra?.feeDirection;
|
|
1589
|
+
const escrow = params.escrow !== void 0 ? params.escrow : params.extra?.escrow !== void 0 ? params.extra?.escrow : config.extra?.escrow;
|
|
1590
|
+
const subAccount = params.subAccountId || params.extra?.subAccountId || params.extra?.account || params.extra?.childAccount || params.account || config.extra?.account;
|
|
1583
1591
|
let payload;
|
|
1584
1592
|
if (isDirect) {
|
|
1585
1593
|
payload = {
|
|
1586
1594
|
name: customer.name,
|
|
1587
1595
|
email: customer.email,
|
|
1588
|
-
phone: customer.phone || "",
|
|
1596
|
+
phone: customer.phone || "081234567890",
|
|
1589
1597
|
amount: integerAmount,
|
|
1590
|
-
notifyUrl
|
|
1598
|
+
notifyUrl,
|
|
1591
1599
|
expired: 24,
|
|
1592
1600
|
expiredType: "hours",
|
|
1593
1601
|
comments: productDetails,
|
|
1594
1602
|
referenceId: orderId,
|
|
1595
1603
|
paymentMethod: ipaymuMethod.paymentMethod,
|
|
1596
1604
|
...ipaymuMethod.paymentChannel ? { paymentChannel: ipaymuMethod.paymentChannel } : {},
|
|
1605
|
+
...feeDirection ? { feeDirection } : {},
|
|
1606
|
+
...escrow !== void 0 ? { escrow } : {},
|
|
1607
|
+
...subAccount ? { account: subAccount } : {},
|
|
1597
1608
|
...params.providerParams
|
|
1598
1609
|
};
|
|
1599
1610
|
} else {
|
|
1611
|
+
const hasItems = params.items && params.items.length > 0;
|
|
1612
|
+
const product = hasItems ? params.items.map((i) => i.name) : [productDetails.length > 50 ? productDetails.substring(0, 47) + "..." : productDetails];
|
|
1613
|
+
const qty = hasItems ? params.items.map((i) => i.quantity) : [1];
|
|
1614
|
+
const price = hasItems ? params.items.map((i) => Math.round(i.price)) : [integerAmount];
|
|
1615
|
+
const description = hasItems ? params.items.map((i) => i.description || i.name) : [productDetails];
|
|
1600
1616
|
payload = {
|
|
1601
|
-
product
|
|
1602
|
-
qty
|
|
1603
|
-
price
|
|
1604
|
-
description
|
|
1605
|
-
returnUrl:
|
|
1606
|
-
notifyUrl
|
|
1607
|
-
cancelUrl:
|
|
1617
|
+
product,
|
|
1618
|
+
qty,
|
|
1619
|
+
price,
|
|
1620
|
+
description,
|
|
1621
|
+
returnUrl: redirectUrl,
|
|
1622
|
+
notifyUrl,
|
|
1623
|
+
cancelUrl: redirectUrl,
|
|
1608
1624
|
referenceId: orderId,
|
|
1609
1625
|
buyerName: customer.name,
|
|
1610
1626
|
buyerEmail: customer.email,
|
|
1611
|
-
buyerPhone: customer.phone || "",
|
|
1627
|
+
buyerPhone: customer.phone || "081234567890",
|
|
1628
|
+
...feeDirection ? { feeDirection } : {},
|
|
1629
|
+
...escrow !== void 0 ? { escrow } : {},
|
|
1630
|
+
...subAccount ? { account: subAccount } : {},
|
|
1612
1631
|
...params.providerParams
|
|
1613
1632
|
};
|
|
1614
1633
|
}
|
|
@@ -1648,8 +1667,8 @@ var IpaymuProvider = class extends BasePaymentProvider {
|
|
|
1648
1667
|
provider: "ipaymu",
|
|
1649
1668
|
orderId,
|
|
1650
1669
|
amount: integerAmount,
|
|
1651
|
-
reference: resData.TransactionId ? String(resData.TransactionId) : String(resData.SessionId || ""),
|
|
1652
|
-
paymentUrl: resData.Url,
|
|
1670
|
+
reference: resData.TransactionId ? String(resData.TransactionId) : String(resData.SessionId || resData.SessionID || ""),
|
|
1671
|
+
paymentUrl: resData.Url || resData.url,
|
|
1653
1672
|
rawResponse: data
|
|
1654
1673
|
};
|
|
1655
1674
|
if (resData.PaymentNo) {
|
|
@@ -1708,126 +1727,109 @@ var IpaymuProvider = class extends BasePaymentProvider {
|
|
|
1708
1727
|
};
|
|
1709
1728
|
}
|
|
1710
1729
|
async getPaymentMethods(params, config) {
|
|
1711
|
-
const
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
paymentName: "Indomaret",
|
|
1796
|
-
paymentImage: "https://my.ipaymu.com/images/banks/indomaret.png",
|
|
1797
|
-
totalFee: "IDR 5,000",
|
|
1798
|
-
category: "Retail / Gerai"
|
|
1799
|
-
},
|
|
1800
|
-
{
|
|
1801
|
-
paymentMethod: "credit_card",
|
|
1802
|
-
code: "credit_card",
|
|
1803
|
-
paymentName: "Credit / Debit Card (Visa, Mastercard)",
|
|
1804
|
-
paymentImage: "https://my.ipaymu.com/images/banks/cc.png",
|
|
1805
|
-
totalFee: "2.9% + IDR 2,000",
|
|
1806
|
-
category: "Kartu Kredit"
|
|
1807
|
-
},
|
|
1808
|
-
{
|
|
1809
|
-
paymentMethod: "akulaku",
|
|
1810
|
-
code: "akulaku",
|
|
1811
|
-
paymentName: "Akulaku Paylater",
|
|
1812
|
-
paymentImage: "https://my.ipaymu.com/images/banks/akulaku.png",
|
|
1813
|
-
totalFee: "1.7%",
|
|
1814
|
-
category: "Paylater / Cicilan"
|
|
1815
|
-
}
|
|
1816
|
-
];
|
|
1817
|
-
const categories = {};
|
|
1818
|
-
for (const item of staticMethods) {
|
|
1819
|
-
if (!categories[item.category]) {
|
|
1820
|
-
categories[item.category] = [];
|
|
1730
|
+
const va = config.merchantCode || config.merchantId || "";
|
|
1731
|
+
const apiKey = config.apiKey || "";
|
|
1732
|
+
const sandbox = !!config.sandbox;
|
|
1733
|
+
if (!va || !apiKey) {
|
|
1734
|
+
return {
|
|
1735
|
+
success: false,
|
|
1736
|
+
provider: "ipaymu",
|
|
1737
|
+
methods: [],
|
|
1738
|
+
categories: {},
|
|
1739
|
+
error: "Missing iPaymu credentials (BUAYAR_MERCHANT_CODE/VA or BUAYAR_API_KEY)",
|
|
1740
|
+
rawResponse: null
|
|
1741
|
+
};
|
|
1742
|
+
}
|
|
1743
|
+
try {
|
|
1744
|
+
const url = `${this.getBaseUrl(sandbox)}/payment-channels`;
|
|
1745
|
+
const { signature, timestamp } = generateIpaymuSignature("GET", va, apiKey);
|
|
1746
|
+
const response = await fetch(url, {
|
|
1747
|
+
method: "GET",
|
|
1748
|
+
headers: {
|
|
1749
|
+
"Content-Type": "application/json",
|
|
1750
|
+
"Accept": "application/json",
|
|
1751
|
+
"va": va,
|
|
1752
|
+
"signature": signature,
|
|
1753
|
+
"timestamp": timestamp
|
|
1754
|
+
}
|
|
1755
|
+
});
|
|
1756
|
+
const data = await response.json().catch(() => null);
|
|
1757
|
+
if (response.ok && data?.Data && Array.isArray(data.Data)) {
|
|
1758
|
+
const methods = [];
|
|
1759
|
+
const categories = {};
|
|
1760
|
+
for (const group of data.Data) {
|
|
1761
|
+
const groupCode = (group.Code || "").toLowerCase();
|
|
1762
|
+
const groupName = group.Name || group.Description || "Lainnya";
|
|
1763
|
+
const channels = group.Channels || [];
|
|
1764
|
+
let category = "Lainnya";
|
|
1765
|
+
if (groupCode === "va") category = "Virtual Account";
|
|
1766
|
+
else if (groupCode === "cstore") category = "Retail / Gerai";
|
|
1767
|
+
else if (groupCode === "qris") category = "QRIS";
|
|
1768
|
+
else if (groupCode === "cc") category = "Kartu Kredit";
|
|
1769
|
+
else if (groupCode === "paylater") category = "Paylater / Cicilan";
|
|
1770
|
+
else if (groupCode === "cod") category = "COD";
|
|
1771
|
+
else category = groupName;
|
|
1772
|
+
for (const ch of channels) {
|
|
1773
|
+
const chCode = (ch.Code || "").toLowerCase();
|
|
1774
|
+
let canonicalCode = chCode;
|
|
1775
|
+
if (groupCode === "va") {
|
|
1776
|
+
canonicalCode = chCode === "bag" ? "bag_va" : chCode === "bmi" ? "muamalat_va" : `${chCode}_va`;
|
|
1777
|
+
} else if (groupCode === "cc") {
|
|
1778
|
+
canonicalCode = "credit_card";
|
|
1779
|
+
}
|
|
1780
|
+
let totalFee = "-";
|
|
1781
|
+
if (ch.TransactionFee) {
|
|
1782
|
+
if (ch.TransactionFee.ActualFeeType === "PERCENT") {
|
|
1783
|
+
totalFee = `${ch.TransactionFee.ActualFee}%`;
|
|
1784
|
+
} else if (ch.TransactionFee.ActualFee !== void 0) {
|
|
1785
|
+
totalFee = `IDR ${Number(ch.TransactionFee.ActualFee).toLocaleString()}`;
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1788
|
+
const pm = {
|
|
1789
|
+
paymentMethod: canonicalCode,
|
|
1790
|
+
code: canonicalCode,
|
|
1791
|
+
paymentName: ch.Name || ch.Description || canonicalCode,
|
|
1792
|
+
paymentImage: ch.Logo || `https://my.ipaymu.com/images/banks/${chCode}.png`,
|
|
1793
|
+
totalFee,
|
|
1794
|
+
category,
|
|
1795
|
+
extra: {
|
|
1796
|
+
healthStatus: ch.HealthStatus,
|
|
1797
|
+
featureStatus: ch.FeatureStatus,
|
|
1798
|
+
instructionsDoc: ch.PaymentInstructionsDoc,
|
|
1799
|
+
feeDetail: ch.TransactionFee
|
|
1800
|
+
}
|
|
1801
|
+
};
|
|
1802
|
+
methods.push(pm);
|
|
1803
|
+
if (!categories[category]) categories[category] = [];
|
|
1804
|
+
categories[category].push(pm);
|
|
1805
|
+
}
|
|
1806
|
+
}
|
|
1807
|
+
return {
|
|
1808
|
+
success: true,
|
|
1809
|
+
provider: "ipaymu",
|
|
1810
|
+
methods,
|
|
1811
|
+
categories,
|
|
1812
|
+
rawResponse: data
|
|
1813
|
+
};
|
|
1821
1814
|
}
|
|
1822
|
-
|
|
1815
|
+
return {
|
|
1816
|
+
success: false,
|
|
1817
|
+
provider: "ipaymu",
|
|
1818
|
+
methods: [],
|
|
1819
|
+
categories: {},
|
|
1820
|
+
error: data?.Message || data?.message || `Failed to fetch payment channels (HTTP ${response.status})`,
|
|
1821
|
+
rawResponse: data
|
|
1822
|
+
};
|
|
1823
|
+
} catch (err) {
|
|
1824
|
+
return {
|
|
1825
|
+
success: false,
|
|
1826
|
+
provider: "ipaymu",
|
|
1827
|
+
methods: [],
|
|
1828
|
+
categories: {},
|
|
1829
|
+
error: err.message || "Failed to fetch iPaymu payment channels",
|
|
1830
|
+
rawResponse: null
|
|
1831
|
+
};
|
|
1823
1832
|
}
|
|
1824
|
-
return {
|
|
1825
|
-
success: true,
|
|
1826
|
-
provider: "ipaymu",
|
|
1827
|
-
methods: staticMethods,
|
|
1828
|
-
categories,
|
|
1829
|
-
rawResponse: staticMethods
|
|
1830
|
-
};
|
|
1831
1833
|
}
|
|
1832
1834
|
async checkTransaction(params, config) {
|
|
1833
1835
|
const { merchantOrderId } = params;
|
|
@@ -1874,11 +1876,14 @@ var IpaymuProvider = class extends BasePaymentProvider {
|
|
|
1874
1876
|
};
|
|
1875
1877
|
}
|
|
1876
1878
|
const txData = data.Data || {};
|
|
1877
|
-
const
|
|
1878
|
-
const
|
|
1879
|
-
const
|
|
1880
|
-
const
|
|
1881
|
-
const
|
|
1879
|
+
const rawStatus = txData.Status !== void 0 ? txData.Status : txData.status;
|
|
1880
|
+
const statusDesc = (txData.StatusDesc || "").toString().toLowerCase();
|
|
1881
|
+
const paidStatus = (txData.PaidStatus || "").toString().toLowerCase();
|
|
1882
|
+
const statusCode = txData.StatusCode !== void 0 ? Number(txData.StatusCode) : rawStatus !== void 0 ? Number(rawStatus) : void 0;
|
|
1883
|
+
const isPaid = statusCode === 1 || paidStatus === "paid" || statusDesc.includes("berhasil") || statusDesc.includes("success");
|
|
1884
|
+
const isPending = statusCode === 0 || paidStatus === "unpaid" || statusDesc.includes("menunggu") || statusDesc.includes("pending");
|
|
1885
|
+
const isExpired = statusCode === 2 || statusDesc.includes("expired") || statusDesc.includes("kadaluarsa");
|
|
1886
|
+
const isFailed = !isPaid && !isPending && !isExpired;
|
|
1882
1887
|
const status = isPaid ? "paid" : isPending ? "pending" : isExpired ? "expired" : "failed";
|
|
1883
1888
|
return {
|
|
1884
1889
|
success: true,
|
|
@@ -8094,6 +8099,137 @@ var IpaymuClient = class {
|
|
|
8094
8099
|
async checkTransaction(transactionId) {
|
|
8095
8100
|
return this.request("POST", "/transaction", { transactionId });
|
|
8096
8101
|
}
|
|
8102
|
+
/**
|
|
8103
|
+
* Ambil daftar channel pembayaran aktif milik merchant (Official v2: GET /payment-channels)
|
|
8104
|
+
*/
|
|
8105
|
+
async getPaymentMethods() {
|
|
8106
|
+
return this.request("GET", "/payment-channels");
|
|
8107
|
+
}
|
|
8108
|
+
/**
|
|
8109
|
+
* Alias untuk getPaymentMethods (Official v2)
|
|
8110
|
+
*/
|
|
8111
|
+
async getPaymentChannels() {
|
|
8112
|
+
return this.request("GET", "/payment-channels");
|
|
8113
|
+
}
|
|
8114
|
+
/**
|
|
8115
|
+
* Ambil riwayat transaksi merchant berpaginasi (Official v2: POST /history)
|
|
8116
|
+
*/
|
|
8117
|
+
async getHistory(params) {
|
|
8118
|
+
const payload = {
|
|
8119
|
+
account: this.va,
|
|
8120
|
+
page: params?.page || 1,
|
|
8121
|
+
limit: params?.limit || 10,
|
|
8122
|
+
...params
|
|
8123
|
+
};
|
|
8124
|
+
return this.request("POST", "/history", payload);
|
|
8125
|
+
}
|
|
8126
|
+
/**
|
|
8127
|
+
* Ambil daftar seluruh bank di Indonesia (Official v2: POST /banklist)
|
|
8128
|
+
*/
|
|
8129
|
+
async getBankList() {
|
|
8130
|
+
return this.request("POST", "/banklist", { account: this.va });
|
|
8131
|
+
}
|
|
8132
|
+
/**
|
|
8133
|
+
* Cari jangkauan area pengiriman COD (Official v2: GET /cod/area?area=keyword)
|
|
8134
|
+
*/
|
|
8135
|
+
async getCodArea(area) {
|
|
8136
|
+
const query = { area };
|
|
8137
|
+
return this.request("GET", `/cod/area?area=${encodeURIComponent(area)}`, query);
|
|
8138
|
+
}
|
|
8139
|
+
/**
|
|
8140
|
+
* Hitung tarif ongkir pengiriman COD (Official v2: POST /cod/shipping-calculate)
|
|
8141
|
+
*/
|
|
8142
|
+
async getCodRate(params) {
|
|
8143
|
+
const { pickupArea, deliveryArea, ...rest } = params;
|
|
8144
|
+
const pickupId = params.pickup_area_id !== void 0 ? params.pickup_area_id : pickupArea;
|
|
8145
|
+
const destId = params.destination_area_id !== void 0 ? params.destination_area_id : deliveryArea;
|
|
8146
|
+
const payload = {
|
|
8147
|
+
...rest,
|
|
8148
|
+
pickup_area_id: pickupId !== void 0 ? String(pickupId) : void 0,
|
|
8149
|
+
destination_area_id: destId !== void 0 ? String(destId) : void 0,
|
|
8150
|
+
amount: params.amount || 0
|
|
8151
|
+
};
|
|
8152
|
+
return this.request("POST", "/cod/shipping-calculate", payload);
|
|
8153
|
+
}
|
|
8154
|
+
/**
|
|
8155
|
+
* Request pickup kurir COD (Official v2: POST /cod/pickup)
|
|
8156
|
+
*/
|
|
8157
|
+
async getCodPickup(params) {
|
|
8158
|
+
const { transactionId, ...rest } = params;
|
|
8159
|
+
const payload = {
|
|
8160
|
+
...rest,
|
|
8161
|
+
transaction_id: params.transaction_id || transactionId
|
|
8162
|
+
};
|
|
8163
|
+
return this.request("POST", "/cod/pickup", payload);
|
|
8164
|
+
}
|
|
8165
|
+
/**
|
|
8166
|
+
* Unduh label pengiriman / AWB COD (Official v2: GET /cod/download-label/:transaction_id)
|
|
8167
|
+
*/
|
|
8168
|
+
async getCodAwb(transactionId) {
|
|
8169
|
+
return this.request("GET", `/cod/download-label/${transactionId}`);
|
|
8170
|
+
}
|
|
8171
|
+
/**
|
|
8172
|
+
* Lacak status pengiriman kurir COD berdasarkan no resi / AWB (Official v2: POST /cod/tracking)
|
|
8173
|
+
*/
|
|
8174
|
+
async getCodTracking(params) {
|
|
8175
|
+
const payload = typeof params === "string" ? { awb: params } : {
|
|
8176
|
+
awb: params.awb,
|
|
8177
|
+
transaction_id: params.transaction_id || params.transactionId
|
|
8178
|
+
};
|
|
8179
|
+
return this.request("POST", "/cod/tracking", payload);
|
|
8180
|
+
}
|
|
8181
|
+
// ==========================================
|
|
8182
|
+
// Public Area Lookup API (docs.ipaymu.com/en/docs/area-api)
|
|
8183
|
+
// Read-only endpoint untuk provinsi, kota/kabupaten, kecamatan, dan kelurahan
|
|
8184
|
+
// ==========================================
|
|
8185
|
+
/**
|
|
8186
|
+
* Ambil daftar seluruh provinsi di Indonesia
|
|
8187
|
+
*/
|
|
8188
|
+
async getAreasProvince() {
|
|
8189
|
+
const res = await fetch("https://my.ipaymu.com/api/areas/province");
|
|
8190
|
+
return res.json();
|
|
8191
|
+
}
|
|
8192
|
+
/**
|
|
8193
|
+
* Ambil daftar kota / kabupaten berdasarkan ID provinsi
|
|
8194
|
+
*/
|
|
8195
|
+
async getAreasCity(provinceId) {
|
|
8196
|
+
const res = await fetch(`https://my.ipaymu.com/api/areas/city/${provinceId}`);
|
|
8197
|
+
return res.json();
|
|
8198
|
+
}
|
|
8199
|
+
/**
|
|
8200
|
+
* Ambil daftar kecamatan berdasarkan ID kota / kabupaten
|
|
8201
|
+
*/
|
|
8202
|
+
async getAreasDistrict(cityId) {
|
|
8203
|
+
const res = await fetch(`https://my.ipaymu.com/api/areas/district/${cityId}`);
|
|
8204
|
+
return res.json();
|
|
8205
|
+
}
|
|
8206
|
+
/**
|
|
8207
|
+
* Ambil daftar kelurahan berdasarkan ID kecamatan
|
|
8208
|
+
*/
|
|
8209
|
+
async getAreasVillage(districtId) {
|
|
8210
|
+
const res = await fetch(`https://my.ipaymu.com/api/areas/village/${districtId}`);
|
|
8211
|
+
return res.json();
|
|
8212
|
+
}
|
|
8213
|
+
// ==========================================
|
|
8214
|
+
// Split Payment — Single Register API
|
|
8215
|
+
// https://ipaymu.com/en/split-payment/
|
|
8216
|
+
// ==========================================
|
|
8217
|
+
/**
|
|
8218
|
+
* Daftarkan agen / reseller / mitra baru untuk Split Payment (Single Register API: POST /api/v2/register)
|
|
8219
|
+
* Mengembalikan VA child account yang siap digunakan untuk parameter `subAccountId` saat membuat transaksi.
|
|
8220
|
+
*/
|
|
8221
|
+
async registerUser(params) {
|
|
8222
|
+
const { name, email, phone, password, ...rest } = params;
|
|
8223
|
+
const payload = {
|
|
8224
|
+
...rest,
|
|
8225
|
+
account: this.va,
|
|
8226
|
+
name,
|
|
8227
|
+
email,
|
|
8228
|
+
phone,
|
|
8229
|
+
password: password || "Password123!"
|
|
8230
|
+
};
|
|
8231
|
+
return this.request("POST", "/register", payload);
|
|
8232
|
+
}
|
|
8097
8233
|
};
|
|
8098
8234
|
|
|
8099
8235
|
// src/clients/xendit.ts
|
package/docs/guide.md
CHANGED
|
@@ -19,7 +19,8 @@ Panduan ini adalah **satu-satunya** panduan yang Anda butuhkan untuk mengintegra
|
|
|
19
19
|
9. [Provider Dinamis & Autodetect](#-provider-dinamis--autodetect)
|
|
20
20
|
10. [Cek Capability Provider (Portabilitas)](#-cek-capability-provider-portabilitas)
|
|
21
21
|
11. [Fitur Khusus Provider (`<X>Client`)](#-fitur-khusus-provider-xclient)
|
|
22
|
-
12. [
|
|
22
|
+
12. [Panduan Pengisian Variabel Universal (`BUAYAR_*`) per Provider](#-panduan-pengisian-variabel-universal-buayar_-per-provider)
|
|
23
|
+
13. [Daftar Canonical Payment Methods](#-daftar-canonical-payment-methods)
|
|
23
24
|
|
|
24
25
|
---
|
|
25
26
|
|
|
@@ -370,57 +371,59 @@ const balance = await xendit.checkBalance("CASH");
|
|
|
370
371
|
|
|
371
372
|
Rangkuman kemampuan ekstra tiap provider:
|
|
372
373
|
|
|
373
|
-
| Provider | Getter | Kemampuan ekstra |
|
|
374
|
-
| :--- | :--- | :--- |
|
|
375
|
-
| Midtrans | `getMidtransClient()` | cancel/refund/expire/approve/deny/capture, GoPay tokenization, Subscription, Payment Link, IRIS balance |
|
|
376
|
-
| Duitku | `getDuitkuClient()` | balance, listBanks, inquiryBankAccount, disburse, checkDisbursementStatus |
|
|
377
|
-
| iPaymu | `getIpaymuClient()` | balance, checkTransaction |
|
|
378
|
-
| Xendit | `getXenditClient()` | balance, expireInvoice, createDisbursement |
|
|
379
|
-
| DOKU | `getDokuClient()` | checkTransaction |
|
|
380
|
-
| PrismaLink | `getPrismalinkClient()` | checkTransaction |
|
|
381
|
-
| Faspay | `getFaspayClient()` | cancelTransaction, checkTransaction |
|
|
382
|
-
| Finpay | `getFinpayClient()` | checkTransaction |
|
|
383
|
-
| Nicepay | `getNicepayClient()` | cancelTransaction, checkTransaction |
|
|
384
|
-
| OY! Bisnis | `getOyClient()` | checkTransaction, balance, remit (transfer dana) |
|
|
385
|
-
| Stripe | `getStripeClient()` | balance, createRefund, retrieveCheckoutSession, retrievePaymentIntent |
|
|
386
|
-
| PayPal | `getPaypalClient()` | captureOrder, getOrder, refundCapture, checkBalance, verifyWebhookSignature |
|
|
387
|
-
| Adyen | `getAdyenClient()` | capturePayment, cancelPayment, refundPayment, getPaymentDetails, getAvailablePaymentMethods |
|
|
388
|
-
| Checkout.com | `getCheckoutComClient()` | balance, refundPayment, voidPayment, getPaymentDetails, listPaymentLinks |
|
|
389
|
-
| Razorpay | `getRazorpayClient()` | capturePayment, createRefund, checkBalance, fetchPayment, listPayments |
|
|
390
|
-
| Square | `getSquareClient()` | retrieveBalance, refundPayment, cancelPayment, getPayment, listLocations |
|
|
391
|
-
| PayU | `getPayuClient()` | cancelOrder, getOrder, refundOrder |
|
|
392
|
-
| Braintree | `getBraintreeClient()` | getClientToken, findTransaction, refundTransaction, voidTransaction |
|
|
393
|
-
| 2Checkout | `getTwoCheckoutClient()` | getOrder, listOrders, getSubscription, refundOrder |
|
|
374
|
+
| Provider | Status | Getter | Kemampuan ekstra |
|
|
375
|
+
| :--- | :---: | :--- | :--- |
|
|
376
|
+
| Midtrans | - | `getMidtransClient()` | cancel/refund/expire/approve/deny/capture, GoPay tokenization, Subscription, Payment Link, IRIS balance |
|
|
377
|
+
| Duitku | - | `getDuitkuClient()` | balance, listBanks, inquiryBankAccount, disburse, checkDisbursementStatus |
|
|
378
|
+
| [iPaymu](ipaymu.md) | Tested | `getIpaymuClient()` | balance, checkTransaction, getHistory, getBankList, getPaymentMethods/getPaymentChannels, Split Payment (registerUser / subAccountId), COD logistics (getArea, getRate, getPickup, getAwb, getTracking), Public Area API (Province, City, District, Village). *Lihat [panduan lengkap iPaymu](ipaymu.md)* |
|
|
379
|
+
| Xendit | - | `getXenditClient()` | balance, expireInvoice, createDisbursement |
|
|
380
|
+
| DOKU | - | `getDokuClient()` | checkTransaction |
|
|
381
|
+
| PrismaLink | - | `getPrismalinkClient()` | checkTransaction |
|
|
382
|
+
| Faspay | - | `getFaspayClient()` | cancelTransaction, checkTransaction |
|
|
383
|
+
| Finpay | - | `getFinpayClient()` | checkTransaction |
|
|
384
|
+
| Nicepay | - | `getNicepayClient()` | cancelTransaction, checkTransaction |
|
|
385
|
+
| OY! Bisnis | - | `getOyClient()` | checkTransaction, balance, remit (transfer dana) |
|
|
386
|
+
| Stripe | - | `getStripeClient()` | balance, createRefund, retrieveCheckoutSession, retrievePaymentIntent |
|
|
387
|
+
| PayPal | - | `getPaypalClient()` | captureOrder, getOrder, refundCapture, checkBalance, verifyWebhookSignature |
|
|
388
|
+
| Adyen | - | `getAdyenClient()` | capturePayment, cancelPayment, refundPayment, getPaymentDetails, getAvailablePaymentMethods |
|
|
389
|
+
| Checkout.com | - | `getCheckoutComClient()` | balance, refundPayment, voidPayment, getPaymentDetails, listPaymentLinks |
|
|
390
|
+
| Razorpay | - | `getRazorpayClient()` | capturePayment, createRefund, checkBalance, fetchPayment, listPayments |
|
|
391
|
+
| Square | - | `getSquareClient()` | retrieveBalance, refundPayment, cancelPayment, getPayment, listLocations |
|
|
392
|
+
| PayU | - | `getPayuClient()` | cancelOrder, getOrder, refundOrder |
|
|
393
|
+
| Braintree | - | `getBraintreeClient()` | getClientToken, findTransaction, refundTransaction, voidTransaction |
|
|
394
|
+
| 2Checkout | - | `getTwoCheckoutClient()` | getOrder, listOrders, getSubscription, refundOrder |
|
|
394
395
|
|
|
395
396
|
---
|
|
396
397
|
|
|
397
|
-
## 📚
|
|
398
|
-
|
|
399
|
-
Anda
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
|
404
|
-
|
|
|
405
|
-
|
|
|
406
|
-
|
|
|
407
|
-
|
|
|
408
|
-
|
|
|
409
|
-
|
|
|
410
|
-
|
|
|
411
|
-
|
|
|
412
|
-
|
|
|
413
|
-
|
|
|
414
|
-
|
|
|
415
|
-
|
|
|
416
|
-
|
|
|
417
|
-
|
|
|
418
|
-
|
|
|
419
|
-
|
|
|
420
|
-
|
|
|
421
|
-
|
|
|
422
|
-
|
|
423
|
-
|
|
398
|
+
## 📚 Panduan Pengisian Variabel Universal (`BUAYAR_*`) per Provider
|
|
399
|
+
|
|
400
|
+
Anda **tidak perlu** membuat nama variabel khusus per provider (seperti `IPAYMU_API_KEY`, `DUITKU_API_KEY`, dsb.). Cukup gunakan set variabel seragam **`BUAYAR_*`**.
|
|
401
|
+
|
|
402
|
+
Tabel berikut menunjukkan data apa dari dashboard masing-masing payment gateway yang perlu Anda masukkan ke variabel `BUAYAR_*`:
|
|
403
|
+
|
|
404
|
+
| Provider | `BUAYAR_PROVIDER` | `BUAYAR_API_KEY` | `BUAYAR_MERCHANT_CODE` | `BUAYAR_CLIENT_KEY` / Tambahan |
|
|
405
|
+
| :--- | :--- | :--- | :--- | :--- |
|
|
406
|
+
| **Midtrans** | `midtrans` | Server Key | *(opsional)* | Client Key |
|
|
407
|
+
| **Duitku** | `duitku` | API Key | Merchant Code | *(tidak perlu)* |
|
|
408
|
+
| **iPaymu** | `ipaymu` | API Key | Nomor Virtual Account (VA) | *(tidak perlu)* |
|
|
409
|
+
| **Xendit** | `xendit` | Secret Key | *(opsional)* | Webhook Verification Token (`BUAYAR_WEBHOOK_SECRET`) |
|
|
410
|
+
| **DOKU Jokul** | `doku` | Secret Key | Client ID / Merchant ID | Client ID |
|
|
411
|
+
| **PrismaLink** | `prismalink` | Secret Key | Merchant ID | *(tidak perlu)* |
|
|
412
|
+
| **Faspay** | `faspay` | Password | Merchant ID | User ID |
|
|
413
|
+
| **Finpay** | `finpay` | Merchant Key | Merchant ID | *(tidak perlu)* |
|
|
414
|
+
| **Nicepay** | `nicepay` | Server Key (Secret) | I-MID (Merchant ID) | *(tidak perlu)* |
|
|
415
|
+
| **OY! Bisnis** | `oy` | API Key | Username | Username |
|
|
416
|
+
| **Stripe** | `stripe` | Secret Key (`sk_...`) | *(tidak perlu)* | Publishable Key (`pk_...`) / Webhook Secret |
|
|
417
|
+
| **PayPal** | `paypal` | Client Secret | Client ID | Client ID |
|
|
418
|
+
| **Adyen** | `adyen` | API Key | Merchant Account Name | Client Key / HMAC Key (`BUAYAR_WEBHOOK_SECRET`) |
|
|
419
|
+
| **Checkout.com** | `checkoutcom` | Secret Key (`sk_...`) | *(tidak perlu)* | Public Key (`pk_...`) / Webhook Secret |
|
|
420
|
+
| **Razorpay** | `razorpay` | Key Secret | Key ID | Key ID |
|
|
421
|
+
| **Square** | `square` | Access Token | Application ID | Location ID (`BUAYAR_PROJECT_ID`) |
|
|
422
|
+
| **PayU** | `payu` | MD5 Key / Secret | POS ID | POS ID |
|
|
423
|
+
| **Braintree** | `braintree` | Private Key | Merchant ID | Public Key |
|
|
424
|
+
| **2Checkout** | `twocheckout` | Secret Key | Merchant Code | Secret Word (`BUAYAR_WEBHOOK_SECRET`) |
|
|
425
|
+
|
|
426
|
+
> 💡 **Mode Sandbox:** Cukup tambahkan `BUAYAR_SANDBOX=true` (atau `false` saat production), SDK otomatis menyesuaikan URL endpoint API seluruh provider di atas tanpa perlu konfigurasi tambahan.
|
|
424
427
|
|
|
425
428
|
---
|
|
426
429
|
|
|
@@ -428,7 +431,7 @@ Sandbox: otomatis terdeteksi dari `BUAYAR_SANDBOX`/`NODE_ENV`, atau set per-prov
|
|
|
428
431
|
|
|
429
432
|
| Kategori | Canonical Code |
|
|
430
433
|
| :--- | :--- |
|
|
431
|
-
| **Virtual Account** | `bca_va`, `mandiri_va`, `bni_va`, `bri_va`, `permata_va`, `cimb_va`, `danamon_va`, `bsi_va`, `seabank_va` |
|
|
434
|
+
| **Virtual Account** | `bca_va`, `mandiri_va`, `bni_va`, `bri_va`, `permata_va`, `cimb_va`, `danamon_va`, `bsi_va`, `seabank_va`, `bag_va`, `muamalat_va` |
|
|
432
435
|
| **QRIS** | `qris`, `gopay_qris`, `shopeepay_qris`, `nobu_qris` |
|
|
433
436
|
| **E-Wallet** | `gopay`, `shopeepay`, `ovo`, `dana`, `linkaja`, `jenius` |
|
|
434
437
|
| **Retail** | `alfamart`, `indomaret`, `pos` |
|