
Security News
Axios Supply Chain Attack Reaches OpenAI macOS Signing Pipeline, Forces Certificate Rotation
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.
@payos/node
Advanced tools
The payOS Node library provides convenient access to the payOS Merchant API from applications written in JavaScript or Typescript.
To learn how to use payOS Merchant API, checkout our API Reference and Documentation. We also have some examples in Examples.
Node 20 or higher.
npm install @payos/node
[!IMPORTANT] If update from v1, check Migration guide for detail migration.
First you need initialize the client to interacting with payOS Merchant API.
import { PayOS } from '@payos/node';
// or
const { PayOS } = require('@payos/node');
const payos = new PayOS({
clientId: process.env.PAYOS_CLIENT_ID,
apiKey: process.env.PAYOS_API_KEY,
checksumKey: process.env.PAYOS_CHECKSUM_KEY,
// ... other options
});
Then you can interact with payOS Merchant API, example create a payment link using paymentRequests.create().
const paymentLink = await payos.paymentRequests.create({
orderCode: 123,
amount: 2000,
description: 'payment',
returnUrl: 'https://your-url.com',
cancelUrl: 'https://your-url.com',
});
You can register an endpoint to receive the payment webhook.
const confirmResult = await payos.webhooks.confirm('https://your-url.com/payos-webhook');
Then using webhooks.verify() to verify and receive webhook data.
const webhookData = await payos.webhooks.verify({
code: '00',
desc: 'success',
success: true,
data: {
orderCode: 123,
amount: 3000,
description: 'VQRIO123',
accountNumber: '12345678',
reference: 'TF230204212323',
transactionDateTime: '2023-02-04 18:25:00',
currency: 'VND',
paymentLinkId: '124c33293c43417ab7879e14c8d9eb18',
code: '00',
desc: 'Thành công',
counterAccountBankId: '',
counterAccountBankName: '',
counterAccountName: '',
counterAccountNumber: '',
virtualAccountName: '',
virtualAccountNumber: '',
},
signature: '8d8640d802576397a1ce45ebda7f835055768ac7ad2e0bfb77f9b8f12cca4c7f',
});
For more information about webhooks, see the API doc.
When the API return a non-success status code (i.e, 4xx or 5xx response) or non-success code data (any code except '00'), a class APIError or its subclass will be thrown:
payos
.get({
path: '/not-found',
})
.catch((err) => {
if (err instanceof APIError) {
console.log(err.name); // NotFoundError
console.log(err.message); // HTTP 404, {}
console.log(err.status); // 404
console.log(err.headers); // {server: "nginx",...}
console.log(err.code); // undefined
console.log(err.desc); // undefined
} else {
throw err;
}
});
List method in the payOS Merchant API are paginated, You can use the for await ... of syntax to iterate though items across all pages:
const allPayouts = [];
const payoutPage = await payos.payouts.list({ limit: 3 });
for await (const payout of payoutPage) {
allPayouts.push(payout);
}
console.log(allPayouts);
// or
const payouts = await payoutPage.toArray();
console.log(payouts);
Or you can request single page at a time:
let page = await payos.payouts.list({
limit: 3,
});
for (const payout of page.data) {
console.log(payout);
}
while (page.hasNextPage()) {
page = await page.getNextPage();
}
You can customize the PayOS client with various options:
const payos = new PayOS({
clientId: process.env.PAYOS_CLIENT_ID,
apiKey: process.env.PAYOS_API_KEY,
checksumKey: process.env.PAYOS_CHECKSUM_KEY,
partnerCode: process.env.PAYOS_PARTNER_CODE, // Optional partner code
baseURL: 'https://api-merchant.payos.vn', // Custom base URL
timeout: 30000, // Request timeout in milliseconds (default: 60000)
maxRetries: 3, // Maximum retry attempts (default: 2)
logLevel: 'info', // Log level: 'off', 'error', 'warn', 'info', 'debug'
logger: console, // Custom logger implementation
fetchOptions: {
// Additional fetch options
headers: {
'Custom-Header': 'value',
},
},
});
You can provide a custom fetch implementation:
import fetch from 'node-fetch'; // or any other fetch implementation
const payos = new PayOS({
clientId: process.env.PAYOS_CLIENT_ID,
apiKey: process.env.PAYOS_API_KEY,
checksumKey: process.env.PAYOS_CHECKSUM_KEY,
fetch: fetch as any, // Custom fetch function
});
You can override client-level settings for individual requests:
const paymentLink = await payos.paymentRequests.create(
{
orderCode: 123,
amount: 2000,
description: 'payment',
returnUrl: 'https://your-url.com',
cancelUrl: 'https://your-url.com',
},
{
maxRetries: 5, // Override default max retries
timeout: 10000, // Override default timeout
signal: abortController.signal, // AbortSignal for request cancellation
},
);
The log level can be configured in two ways:
PAYOS_LOG environment variable.logLevel client option (override the environment if set).By default, this library logs to globalThis.console. You can also provide a custom logger. If your logger doesn't work, please open an issue.
import { createLogger } from 'winston';
const payos = new PayOS({
clientId: process.env.PAYOS_CLIENT_ID,
apiKey: process.env.PAYOS_API_KEY,
checksumKey: process.env.PAYOS_CHECKSUM_KEY,
logLevel: 'debug', // Enable debug logging
logger: createLogger({
level: 'debug',
transports: [new transports.Console()],
}),
});
For advanced use cases, you can make direct API calls:
// GET request
const response = await payos.get('/v2/payment-requests');
// POST request
const response = await payos.post('/v2/payment-requests', {
body: {
orderCode: 123,
amount: 2000,
description: 'payment',
returnUrl: 'https://your-url.com',
cancelUrl: 'https://your-url.com',
},
});
// With custom options
const response = await payos.request({
method: 'POST',
path: '/v2/payment-requests',
body: requestData,
maxRetries: 3,
timeout: 15000,
});
The signature can be manually created by PayOS.crypto:
// for create-payment-link signature
const signature = await payos.crypto.createSignatureOfPaymentRequest(data, payos.checksumKey);
// of
const signature = await payos.crypto.createSignatureFromObj(
{ amount, cancelUrl, description, orderCode, returnUrl },
payos.checksumKey,
);
// for payment-requests and webhook signature
const signature = await payos.crypto.createSignatureFromObj(data, payos.checksumKey);
// for payouts signature
const signature = await payos.crypto.createSignature(payos.checksumKey, data);
FAQs
payOS Node SDK
The npm package @payos/node receives a total of 2,808 weekly downloads. As such, @payos/node popularity was classified as popular.
We found that @payos/node demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.

Security News
Open source is under attack because of how much value it creates. It has been the foundation of every major software innovation for the last three decades. This is not the time to walk away from it.

Security News
Socket CEO Feross Aboukhadijeh breaks down how North Korea hijacked Axios and what it means for the future of software supply chain security.