roedyrustam/vibes-plug/doku-payment-gateway

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

DOKU payment gateway: Checkout, SNAP BI (VA, QRIS), and webhooks / Gateway pembayaran DOKU: Checkout, SNAP BI (VA, QRIS), dan webhook.

Install

npx vskill@latest install roedyrustam/vibes-plug/doku-payment-gateway

SKILL.md

DOKU Payment Gateway Integration / Integrasi Payment Gateway DOKU

English | Bahasa Indonesia


<a name="english"></a>

English

Orchestration & Integration
  • Payments & Multi-Gateway Routing: payment-gateway-expert, saas-billing, agentic-m2m-settlement, agentic-micro-economy-architect
  • AI Agentic Commerce & MCP: doku-mcp-server, mcp-server-architect, ai-llm-integration-expert
  • Database & Atomic Idempotency: database-orm-expert, saas-multi-tenant
  • Security & Post-Quantum Crypto: post-quantum-crypto-migrator, zero-trust-secret-vault, autonomous-red-teamer
  • Async Processing & Observability: async-queue-temporal-expert, data-telemetry-expert
  • Lifecycle & Governance: brainstorming, zero-to-prod-orchestrator, session-memory-manager, anti-slop
Description

Expert guide for implementing DOKU Payment Gateway based on the official DOKU Developers Documentation. DOKU offers two primary integration models:

  1. DOKU Checkout (/checkout/v1/payment): Hosted payment page or modal overlay (jokul-checkout-1.0.0.js). The fastest, single-integration solution supporting all payment channels (Virtual Accounts, Credit Cards, QRIS, E-Wallets, Convenience Stores, Paylater, Direct Debit) with built-in retry handling and cart recovery. Uses Non-SNAP HMAC-SHA256 signatures with request digest.
  2. Direct API:
  • SNAP BI Standard (Host-to-Host): Standardized open banking API mandated by Bank Indonesia. Employs OAuth 2.0 B2B token with Asymmetric RSA-SHA256, and HMAC-SHA512 for transactional endpoints (Direct VA, Direct QRIS, Direct Debit).
  • Non-SNAP Direct API: Dedicated APIs for Credit Card Payment Page (/credit-card/v1/payment-page), OVO Push Payment (/ovo-emoney/v1/payment), and Direct Paylater.

Integration Architecture Decision Matrix
DimensionDOKU Checkout (Hosted / Modal)Direct API (SNAP BI Standard)Direct API (Non-SNAP)
Primary Use CaseE-commerce, SaaS billing, mobile apps wanting instant multi-channel coverageBespoke in-app banking UI, automated dynamic VA generation, native QRIS displayNon-PCI DSS Card custom page, instant OVO push payment to phone
Supported ChannelsAll channels in 1 API (VA, CC, QRIS, E-Wallet, Alfa/Indomaret, Paylater, Direct Debit)Specific endpoints: Bank Virtual Accounts, QRIS, Direct DebitCredit Card 3DS, OVO Push, LinkAja, Paylater (Kredivo/Akulaku)
Frontend EffortMinimal: Redirect to URL or trigger modal via loadJokulCheckout()High: Merchant builds custom payment UI for each channelMedium: Merchant embeds card iframe/redirect or prompts phone
Signature AlgorithmHMACSHA256 with body DigestHMAC-SHA512 (Transactional) + RSA-SHA256 (B2B Token)HMACSHA256 with Digest (Card) or SHA256 checksum (OVO)
Endpoint Base/checkout/v1/payment/virtual-accounts/bi-snap-va/v1.1/..., /snap-adapter/b2b/v1.0/qr/.../credit-card/v1/payment-page, /ovo-emoney/v1/payment
Check StatusGET /orders/v1/status/{invoice_number} (with order-level status)Channel status endpoint (e.g. /transfer-va/status, /qr-mpm-query)GET /orders/v1/status/{invoice_number}

Core Architecture & Credentials
Environment Gateways
EnvironmentBase URLDashboard PortalSimulator
Sandboxhttps://api-sandbox.doku.comhttps://sandbox.doku.comhttps://sandbox.doku.com/gtw-config-v2/simulator
Productionhttps://api.doku.comhttps://dashboard.doku.comN/A
Frontend JS SDK (for Modal Popup Mode)
  • Sandbox: https://sandbox.doku.com/jokul-checkout-js/v1/jokul-checkout-1.0.0.js
  • Production: https://jokul.doku.com/jokul-checkout-js/v1/jokul-checkout-1.0.0.js

1. DOKU Checkout Integration (Recommended)

Backend: Generate Checkout Payment URL
Endpoint
  • HTTP Method: POST
  • Sandbox: https://api-sandbox.doku.com/checkout/v1/payment
  • Production: https://api.doku.com/checkout/v1/payment
Mandatory Headers
http
Client-Id: MCH-0001-10791114622547
Request-Id: 2ebffd22-d23e-4368-95ce-5c38f7ddcf86
Request-Timestamp: 2026-10-03T01:30:00Z
Signature: HMACSHA256=1jap2tpgvWt83tG4J7IhEwUrwmMt71OaIk0oL0e6sPM=
Content-Type: application/json
[!IMPORTANT]
- Request-Timestamp MUST be in ISO8601 UTC+0 (YYYY-MM-DDTHH:mm:ssZ). For WIB (UTC+7), subtract 7 hours.
- Request-Target is /checkout/v1/payment.
Signature Generation (Non-SNAP HMAC-SHA256)
  1. Calculate Digest:

``typescript const jsonBody = JSON.stringify(body); const digest = crypto.createHash('sha256').update(jsonBody, 'utf8').digest('base64'); ``

  1. Assemble Component String:

``text Client-Id:<client-id>\nRequest-Id:<request-id>\nRequest-Timestamp:<timestamp>\nRequest-Target:<request-target>\nDigest:<digest> ``

  1. Calculate HMAC-SHA256:

``typescript const hmac = crypto.createHmac('sha256', secretKey).update(componentString, 'utf8').digest('base64'); const signatureHeader = HMACSHA256=${hmac}; ``

Full Request Payload Schema
json
{
"order": {
"amount": 150000,
"invoice_number": "INV-20261003-0001",
"currency": "IDR",
"callback_url": "https://myapp.com/checkout/return",
"callback_url_cancel": "https://myapp.com/checkout/cancel",
"callback_url_result": "https://myapp.com/checkout/result",
"language": "EN",
"auto_redirect": true,
"disable_retry_payment": true,
"recover_abandoned_cart": true,
"expired_recovered_cart": 60,
"line_items": [
{
"id": "ITEM-1",
"name": "Pro SaaS Annual Subscription",
"quantity": 1,
"price": 150000,
"sku": "SAAS-PRO-Y",
"category": "services"
}
]
},
"payment": {
"payment_due_date": 60,
"payment_method_types": [
"VIRTUAL_ACCOUNT_BCA",
"VIRTUAL_ACCOUNT_BANK_MANDIRI",
"VIRTUAL_ACCOUNT_BRI",
"VIRTUAL_ACCOUNT_BNI",
"CREDIT_CARD",
"QRIS",
"EMONEY_SHOPEEPAY",
"EMONEY_OVO",
"EMONEY_DANA"
]
},
"customer": {
"id": "CUST-9921",
"name": "Alex",
"last_name": "Kusuma",
"email": "alex.kusuma@example.com",
"phone": "6281234567890",
"address": "Sudirman Central Business District",
"city": "Jakarta Selatan",
"country": "ID"
},
"additional_info": {
"allow_tenor": [0, 3, 6, 12],
"override_notification_url": "https://myapp.com/api/webhooks/doku/checkout"
}
}
[!TIP]
To showcase all available channels enabled in your DOKU account, simply omit payment.payment_method_types.
Response Body Highlights
json
{
"message": ["SUCCESS"],
"response": {
"order": {
"amount": "150000",
"invoice_number": "INV-20261003-0001",
"session_id": "5f6304ca900144c7a4fcf802ad6c0898"
},
"payment": {
"url": "https://sandbox.doku.com/checkout-link-v2/5f6304ca900144c7a4fcf802ad6c0898...",
"token_id": "5f6304ca900144c7a4fcf802ad6c08982024...",
"payment_due_date": 60,
"expired_date": "20261003104531"
}
}
}

Frontend Integration (Popup Modal vs Redirect)
Approach A: Modal Overlay (Pop-Up Mode)

Import the DOKU Checkout JS SDK and trigger loadJokulCheckout(url):

html
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Mandatory for responsive modal scaling -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://sandbox.doku.com/jokul-checkout-js/v1/jokul-checkout-1.0.0.js"></script>
</head>
<body>
<button id="pay-button" class="btn-primary">Pay with DOKU</button>
<script>
document.getElementById('pay-button').addEventListener('click', async () => {
// 1. Fetch payment URL from your backend
const res = await fetch('/api/checkout/initiate', { method: 'POST' });
const data = await res.json();
// 2. Open DOKU Checkout modal overlay
if (data.paymentUrl) {
window.loadJokulCheckout(data.paymentUrl);
}
});
</script>
</body>
</html>
Approach B: Direct Redirect Mode

For mobile browsers or standard redirects, navigate directly to response.payment.url:

typescript
window.location.href = data.paymentUrl;

Order Status & Check Status API (Non-SNAP)

The Check Status API tracks order-level statuses even before the customer selects a specific channel:

  • Endpoint: GET https://api-sandbox.doku.com/orders/v1/status/{invoice_number}
  • Signature for GET: Does NOT require a Digest.

``text Client-Id:<client-id>\nRequest-Id:<request-id>\nRequest-Timestamp:<timestamp>\nRequest-Target:/orders/v1/status/<invoice_number> ``

  • Statuses:
  • order.status: ORDER_GENERATED, ORDER_EXPIRED, ORDER_RECOVERED.
  • transaction.status: PENDING, SUCCESS, FAILED, EXPIRED, REFUNDED.

Webhook Verification & Atomic Idempotency (DOKU Checkout)

When a customer completes payment via Checkout, DOKU posts an HTTP Notification with headers:

  • Client-Id, Request-Id, Request-Timestamp, Signature: HMACSHA256=...
typescript
import crypto from 'crypto';
export function verifyDokuCheckoutNotification(
clientId: string,
secretKey: string,
requestTarget: string, // path of your notification endpoint e.g., '/api/webhooks/doku/checkout'
headers: Record<string, string>,
rawBody: string
): boolean {
const reqClientId = headers['client-id'];
const reqId = headers['request-id'];
const reqTimestamp = headers['request-timestamp'];
const receivedSig = headers['signature'] || '';
if (reqClientId !== clientId) return false;
// 1. Compute Base64 SHA-256 Digest of raw body
const digest = crypto.createHash('sha256').update(rawBody, 'utf8').digest('base64');
// 2. Build string component
const component = `Client-Id:${reqClientId}\nRequest-Id:${reqId}\nRequest-Timestamp:${reqTimestamp}\nRequest-Target:${requestTarget}\nDigest:${digest}`;
// 3. Compute HMAC-SHA256
const expectedSig = 'HMACSHA256=' + crypto.createHmac('sha256', secretKey).update(component, 'utf8').digest('base64');
return crypto.timingSafeEqual(Buffer.from(receivedSig), Buffer.from(expectedSig));
}

2. Direct API — SNAP BI Standard (Host-to-Host)

For merchants requiring fully custom, native checkout experiences for Virtual Accounts, QRIS, or Direct Debit.

Step 1: B2B Access Token Generation
  • Endpoint: POST /authorization/v1/access-token/b2b
  • Headers:
  • X-CLIENT-KEY: Merchant Client ID
  • X-TIMESTAMP: ISO8601 string (YYYY-MM-DDTHH:mm:ssZ)
  • X-SIGNATURE: SHA256withRSA(PrivateKey, X-CLIENT-KEY + "|" + X-TIMESTAMP) (Base64)
  • Body: {"grantType": "client_credentials"}
  • Response: accessToken (Bearer token, valid for 900 seconds).
typescript
export function generateSnapB2bSignature(clientId: string, timestamp: string, privateKeyPem: string): string {
const stringToSign = `${clientId}|${timestamp}`;
const signer = crypto.createSign('RSA-SHA256');
signer.update(stringToSign);
return signer.sign(privateKeyPem, 'base64');
}
Step 2: Transactional Endpoints Signature (HMAC-SHA512)
  • Formula:
  1. BodyHash = hex(sha256(minifiedBody)).toLowerCase()
  2. StringToSign = HTTPMethod + ":" + EndpointUrl + ":" + AccessToken + ":" + BodyHash + ":" + Timestamp
  3. X-SIGNATURE = base64(hmacSha512(ClientSecret, StringToSign))
typescript
export function generateSnapTransactionalSignature(
method: string,
endpointPath: string,
accessToken: string,
timestamp: string,
clientSecret: string,
body?: object
): string {
let bodyHash = '';
if (body && ['POST', 'PUT', 'PATCH'].includes(method.toUpperCase())) {
bodyHash = crypto.createHash('sha256').update(JSON.stringify(body), 'utf8').digest('hex').toLowerCase();
}

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
51
Repository forks
10
7-day trend score
20

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/roedyrustam/vibes-plug/doku-payment-gateway/badge)](https://verified-skill.com/skills/roedyrustam/vibes-plug/doku-payment-gateway)

Something wrong with this skill or its page? Tell us.