@hwsdev/yupay
v1.0.3
Published
Official Node.js SDK for the Yupay merchant API (charges, refunds, balance, webhooks).
Maintainers
Readme
Yupay Node.js SDK
Official Node.js client for the Yupay merchant API. Zero dependencies (global fetch + crypto), Node 18+. Ships TypeScript types.
Website & docs: yupay.id · Dashboard · API reference
Install
npm install @hwsdev/yupayQuickstart
const { Yupay, YupayError } = require('@hwsdev/yupay');
const yupay = new Yupay(process.env.YUPAY_API_KEY, {
baseUrl: 'https://yupay.id/api/v1', // your Yupay instance
});
try {
const charge = await yupay.createCharge(
{ amount: 50000, method: 'qris' },
{ idempotencyKey: 'order-1001' },
);
console.log(charge.payment_no, charge.status); // PAY-260626-AB12CD pending
console.log(charge.artifact); // qr_string / va_number / redirect_url …
} catch (err) {
if (err instanceof YupayError) {
console.error(err.message, err.statusCode, err.validationErrors);
}
}ESM works too: import { Yupay, webhooks } from '@hwsdev/yupay';
Methods
yupay.createCharge(params, { idempotencyKey? }): Promise<Payment>;
yupay.retrieveCharge(paymentNo): Promise<Payment>;
yupay.refundCharge(paymentNo, { amount?, reason? }): Promise<RefundResult>;
yupay.balance(): Promise<Balance>;
yupay.paymentChannels({ category?, all? }): Promise<ChannelList>;All reject with YupayError (.statusCode, .response, .validationErrors) on failure.
Webhooks (Express)
You must verify the signature against the raw body, so register the route with express.raw (not express.json):
const express = require('express');
const { webhooks } = require('@hwsdev/yupay');
const app = express();
const secret = process.env.YUPAY_WEBHOOK_SECRET;
app.post('/yupay/webhook', express.raw({ type: 'application/json' }), (req, res) => {
let event;
try {
event = webhooks.constructEvent(req.body, req.get('X-Yupay-Signature'), secret);
} catch {
return res.status(400).send('invalid signature');
}
// Dedupe on event.id (Yupay delivers at least once), then handle:
if (event.event === 'payment.succeeded') {
const p = event.data;
// fulfillOrder(p.payment_no, p.amount) — offload heavy work to a queue
}
res.status(200).send('ok'); // ack fast
});
app.listen(3000);Test your handler without real payments: in the dashboard (Developer → Webhooks) use Kirim test or Simulasi to send a signed event to this endpoint, then check the delivery log — it shows your endpoint's response body, so a failed
constructEvent()(HTTP 400) is easy to spot. See webhooks docs.
See examples/ for runnable scripts.
Links
- Website: yupay.id
- Dashboard: app.yupay.id
- Documentation: yupay.id/docs
- Support: [email protected]
