@ecoleafcom/ppc-bank-sdk
v1.0.3
Published
A lightweight JavaScript SDK to integrate with PPCBank Open Banking Platform (OBP) and Payment Gateway APIs, enabling seamless access to banking services like payments, balance, transactions, and virtual accounts.
Readme
PPCBank Payment Gateway SDK
Typed JavaScript/TypeScript SDK for PPCBank Payment Gateway bearer-token authentication and the Mayura KHQR payment flow.
This SDK is based on the PPCB Payment Gateway API Mayura document. It supports:
POST /security_checkfor bearer-token authenticationPOST /api/v1/PMS1011to generate a KHQR payment URLPOST /api/v1/PMS1014to generate a raw KHQR stringPOST /api/v1/PMS1024to check KHQR payment status- Raw authenticated
get,post, andrequestcalls for other PPCBank endpoints
Install
npm install @ecoleafcom/ppc-bank-sdkEnvironment
Create an .env file in your app:
NODE_ENV=development
PPCBANK_BASE_URL=https://paytest.ppcbank.com.kh
PPCBANK_AUTH_PATH=/security_check
PPCBANK_MERCHANT_CODE=YOUR_MERCHANT_CODE
PPCBANK_PASSWORD=YOUR_PASSWORD
PPCBANK_GENERATE_KHQR_PAYMENT_URL_PATH=/api/v1/PMS1011
PPCBANK_GENERATE_KHQR_QR_STRING_PATH=/api/v1/PMS1014
PPCBANK_CHECK_KHQR_PAYMENT_STATUS_PATH=/api/v1/PMS1024NODE_ENV=development is fine for local development. If PPCBANK_DEVELOPER_BASE_URL is not set, the SDK uses PPCBANK_BASE_URL. The SDK also accepts NODE_ENV=developement for compatibility with the common misspelling.
Basic Setup
import { PpcBankPaymentGatewaySdk } from "@ecoleafcom/ppc-bank-sdk";
const ppcBank = new PpcBankPaymentGatewaySdk({
baseUrl: process.env.PPCBANK_BASE_URL,
authPath: process.env.PPCBANK_AUTH_PATH,
credentials: {
merchantCode: process.env.PPCBANK_MERCHANT_CODE!,
password: process.env.PPCBANK_PASSWORD!,
},
});CommonJS:
const { PpcBankPaymentGatewaySdk } = require("@ecoleafcom/ppc-bank-sdk");Authenticate
const auth = await ppcBank.authenticate();
console.log(auth.token);
console.log(auth.raw);The SDK reads PPCBank's documented response shape:
{
"header": {
"result": true,
"resultCode": "100000",
"resultMessage": ""
},
"body": {
"token": "JWT_TOKEN",
"merchantCode": "00000174"
}
}Authenticated SDK calls automatically send:
Authorization: Bearer <token>Generate KHQR Payment URL
Uses POST /api/v1/PMS1011.
const response = await ppcBank.generateKhqrPaymentUrl({
body: {
billNumber: "ORDER-1001",
amount: 1.8,
currencyCode: "USD",
terminalLabel: "",
mobileNumber: "",
storeLabel: "",
},
});
console.log(response.data.body.paymentURL);The SDK automatically wraps the request in the PPCBank header/body envelope and fills merchantCode from credentials when omitted:
{
"header": {
"languageCode": "01",
"channelTypeCode": "03"
},
"body": {
"merchantCode": "YOUR_MERCHANT_CODE",
"billNumber": "ORDER-1001",
"amount": 1.8,
"currencyCode": "USD"
}
}Generate KHQR QR String
Uses POST /api/v1/PMS1014.
const response = await ppcBank.generateKhqrQrString({
body: {
billNumber: "ORDER-1001",
amount: 1.8,
currencyCode: "USD",
},
});
console.log(response.data.body.qrCodeString ?? response.data.body.qrStringCode);Check KHQR Payment Status
Uses POST /api/v1/PMS1024.
const response = await ppcBank.checkKhqrPaymentStatus({
body: {
billNumber: "ORDER-1001",
},
});
console.log(response.data.body.resultYN);
console.log(response.data.body.billStatusCode);
console.log(response.data.body.referenceNo);resultYN is documented as:
Y: paidN: not yet paid
billStatusCode is documented as:
01: success04: cancel05: refund
Raw REST Calls
Use post, get, or request for endpoints that are not wrapped by a convenience method.
const response = await ppcBank.post("/api/v1/PMS1024", {
header: {
languageCode: "01",
channelTypeCode: "03",
},
body: {
merchantCode: process.env.PPCBANK_MERCHANT_CODE!,
billNumber: "ORDER-1001",
},
});
console.log(response.data);Configure Endpoint Overrides
Defaults are already set for the Mayura KHQR endpoints. Override them only if PPCBank gives you different paths.
const ppcBank = new PpcBankPaymentGatewaySdk({
baseUrl: "https://paytest.ppcbank.com.kh",
credentials: {
merchantCode: "YOUR_MERCHANT_CODE",
password: "YOUR_PASSWORD",
},
endpoints: {
generateKhqrPaymentUrl: "/api/v1/PMS1011",
generateKhqrQrString: "/api/v1/PMS1014",
checkKhqrPaymentStatus: "/api/v1/PMS1024",
},
});Error Handling
import { PpcBankApiError, PpcBankAuthenticationError } from "@ecoleafcom/ppc-bank-sdk";
try {
await ppcBank.checkKhqrPaymentStatus({
body: {
billNumber: "ORDER-1001",
},
});
} catch (error) {
if (error instanceof PpcBankApiError) {
console.error(error.status);
console.error(error.data);
}
if (error instanceof PpcBankAuthenticationError) {
console.error(error.message);
}
throw error;
}Separate Sample Project
This repository includes a separate consumer project in test/.
cd test
npm install
npm start
npm run auth
npm run payment
npm run qr
npm run status
npm run restCommands:
npm run auth: authenticate and print a token previewnpm run payment: generate a KHQR payment URL with PMS1011npm run qr: generate a raw KHQR string with PMS1014npm run status: check payment status with PMS1024npm run rest: send a raw authenticated POST usingSAMPLE_REST_PATH
Notes
- Test base URL from the Mayura PDF:
https://paytest.ppcbank.com.kh - Default auth path:
/security_check - Auth request body:
{ "merchantCode": "...", "password": "..." } - Default KHQR request header:
{ "languageCode": "01", "channelTypeCode": "03" } - Tokens are stored in the SDK instance after
authenticate()and are created automatically before authenticated requests when credentials are configured.
