Doku Payment Gateway logo

Doku Payment Gateway

Community
roedyrustam
doku-payment-gateway

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

Overview

Publisherroedyrustam
Repositoryvibes-plug
Skill namedoku-payment-gateway
Stars
117
Forks
27
Bundled files
Instructions only
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by roedyrustam on GitHub. Read the source before you install it.

Installation

Install the Doku Payment Gateway AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/roedyrustam/vibes-plug/tree/main/skills/doku-payment-gateway
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/roedyrustam/vibes-plug.git /tmp/vibes-plug
mkdir -p .claude/skills
cp -r /tmp/vibes-plug/skills/doku-payment-gateway .claude/skills/doku-payment-gateway
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Doku Payment Gateway in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Doku Payment Gateway on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Doku Payment Gateway is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

DOKU Payment Gateway Integration / Integrasi Payment Gateway DOKU

English | Bahasa Indonesia


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');
  2. Assemble Component String:
    text
    Client-Id:<client-id>\nRequest-Id:<request-id>\nRequest-Timestamp:<timestamp>\nRequest-Target:<request-target>\nDigest:<digest>
  3. 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();
  }

  const stringToSign = `${method.toUpperCase()}:${endpointPath}:${accessToken}:${bodyHash}:${timestamp}`;
  return crypto.createHmac('sha512', clientSecret).update(stringToSign, 'utf8').digest('base64');
}

Direct Virtual Account API (/virtual-accounts/bi-snap-va/v1.1/...)

  1. DOKU Generated Payment Code (DGPC):
    • POST /virtual-accounts/bi-snap-va/v1.1/transfer-va/create-va
    • DOKU generates the unique VA number using the bank's BIN.
  2. Merchant Generated Payment Code (MGPC):
    • Merchant provides their own payment code conforming to bank BIN rules.
  3. Billing Types:
    • FIX_BILL: Exact amount payment (standard e-commerce).
    • NO_BILL: Open amount (donations/wallet top-up).
    • BILL_VARIABLE_AMOUNT: Range-based amount.
    • PARTIAL_AMOUNT: Installment or partial payments (BNI, CIMB, Danamon).
  4. Maintenance Endpoints:
    • Update VA: PUT /virtual-accounts/bi-snap-va/v1.1/transfer-va/update-va
    • Delete VA: DELETE /virtual-accounts/bi-snap-va/v1.1/transfer-va/delete-va

Direct QRIS API (/snap-adapter/b2b/v1.0/qr/...)

  1. Generate QRIS:
    • POST /snap-adapter/b2b/v1.0/qr/qr-mpm-generate
    • Request includes partnerReferenceNo, amount.value (format 10000.00), merchantId, terminalId, additionalInfo.postalCode.
    • Response returns qrContent string (EMVCo payload) for rendering dynamic QR code.
  2. Query QRIS: POST /snap-adapter/b2b/v1.0/qr/qr-mpm-query
  3. Cancel / Expire QRIS: POST /snap-adapter/b2b/v1.0/qr/qr-expire
  4. Refund QRIS: POST /snap-adapter/b2b/v1.0/qr/qr-mpm-refund

3. Direct API — Non-SNAP Channels

Credit Card Payment Page (/credit-card/v1/payment-page)

For non-PCI DSS merchants wanting a customized branded card checkout page:

  • Method: POST
  • Headers: Non-SNAP Client-Id, Request-Id, Request-Timestamp, Signature (HMAC-SHA256 with Digest).
  • Body: order, customer, payment.type ("SALE" or "AUTHORIZE"), override_configuration.themes (custom colors and logos).
  • Flow: Redirects customer to DOKU 3D-Secure authentication, then returns to callback_url.

OVO Push Payment (/ovo-emoney/v1/payment)

Initiates an instant push payment notification directly to customer's OVO mobile app:

  • Method: POST
  • Body:
    json
    {
      "client": { "id": "MCH-0001-10791114622547" },
      "order": { "invoice_number": "INV-20261003-0002", "amount": 50000 },
      "ovo_info": { "ovo_id": "081234567890" },
      "security": { "check_sum": "<sha256_checksum>" }
    }
  • Checksum Calculation:
    typescript
    const checkSum = crypto.createHash('sha256')
      .update(`${amount}${clientId}${invoiceNumber}${ovoId}${secretKey}`, 'utf8')
      .digest('hex');
  • Wait Time: The backend request waits up to 70 seconds for the customer to confirm the payment on their phone.

Complete TypeScript Implementation (DOKU Checkout & SNAP Direct)

typescript
import crypto from 'crypto';

export interface DokuConfig {
  clientId: string;
  secretKey: string;
  isProduction: boolean;
  privateKeyPem?: string; // For SNAP B2B RSA token
}

export class DokuService {
  private clientId: string;
  private secretKey: string;
  private baseUrl: string;
  private privateKeyPem?: string;

  constructor(config: DokuConfig) {
    this.clientId = config.clientId;
    this.secretKey = config.secretKey;
    this.baseUrl = config.isProduction ? 'https://api.doku.com' : 'https://api-sandbox.doku.com';
    this.privateKeyPem = config.privateKeyPem;
  }

  // =================== DOKU CHECKOUT (NON-SNAP) ===================
  private generateNonSnapHeaders(targetPath: string, body?: object) {
    const requestId = crypto.randomUUID();
    const timestamp = new Date().toISOString().replace(/\.\d{3}Z$/, 'Z');
    let component = `Client-Id:${this.clientId}\nRequest-Id:${requestId}\nRequest-Timestamp:${timestamp}\nRequest-Target:${targetPath}`;

    const headers: Record<string, string> = {
      'Client-Id': this.clientId,
      'Request-Id': requestId,
      'Request-Timestamp': timestamp,
      'Request-Target': targetPath,
    };

    if (body) {
      const minified = JSON.stringify(body);
      const digest = crypto.createHash('sha256').update(minified, 'utf8').digest('base64');
      headers['Digest'] = digest;
      headers['Content-Type'] = 'application/json';
      component += `\nDigest:${digest}`;
    }

    const hmac = crypto.createHmac('sha256', this.secretKey).update(component, 'utf8').digest('base64');
    headers['Signature'] = `HMACSHA256=${hmac}`;

    return headers;
  }

  public async createCheckoutUrl(payload: {
    amount: number;
    invoiceNumber: string;
    customerName: string;
    customerEmail: string;
    callbackUrl?: string;
  }) {
    const targetPath = '/checkout/v1/payment';
    const body = {
      order: {
        amount: payload.amount,
        invoice_number: payload.invoiceNumber,
        currency: 'IDR',
        callback_url: payload.callbackUrl,
        auto_redirect: true,
      },
      payment: { payment_due_date: 60 },
      customer: {
        id: payload.customerEmail,
        name: payload.customerName,
        email: payload.customerEmail,
      },
    };

    const response = await fetch(`${this.baseUrl}${targetPath}`, {
      method: 'POST',
      headers: this.generateNonSnapHeaders(targetPath, body),
      body: JSON.stringify(body),
    });

    const data = await response.json();
    return {
      paymentUrl: data.response.payment.url,
      tokenId: data.response.payment.token_id,
    };
  }

  // =================== SNAP BI DIRECT API ===================
  public async getSnapB2bToken(): Promise<string> {
    if (!this.privateKeyPem) throw new Error('Private key PEM required for SNAP B2B Token');
    const targetPath = '/authorization/v1/access-token/b2b';
    const timestamp = new Date().toISOString().replace(/\.\d{3}Z$/, 'Z');
    
    // RSA-SHA256 signature
    const stringToSign = `${this.clientId}|${timestamp}`;
    const signer = crypto.createSign('RSA-SHA256');
    signer.update(stringToSign);
    const signature = signer.sign(this.privateKeyPem, 'base64');

    const response = await fetch(`${this.baseUrl}${targetPath}`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-CLIENT-KEY': this.clientId,
        'X-TIMESTAMP': timestamp,
        'X-SIGNATURE': signature,
      },
      body: JSON.stringify({ grantType: 'client_credentials' }),
    });

    const data = await response.json();
    return data.accessToken;
  }

  public async generateDirectQris(accessToken: string, partnerRefNo: string, amount: number, merchantId: string, terminalId: string) {
    const targetPath = '/snap-adapter/b2b/v1.0/qr/qr-mpm-generate';
    const timestamp = new Date().toISOString().replace(/\.\d{3}Z$/, 'Z');
    const externalId = crypto.randomUUID();

    const body = {
      partnerReferenceNo: partnerRefNo,
      amount: { value: `${amount.toFixed(2)}`, currency: 'IDR' },
      merchantId,
      terminalId,
      additionalInfo: { postalCode: '12012', feeType: '1' }
    };

    const minified = JSON.stringify(body);
    const bodyHash = crypto.createHash('sha256').update(minified, 'utf8').digest('hex').toLowerCase();
    const stringToSign = `POST:${targetPath}:${accessToken}:${bodyHash}:${timestamp}`;
    const signature = crypto.createHmac('sha512', this.secretKey).update(stringToSign, 'utf8').digest('base64');

    const response = await fetch(`${this.baseUrl}${targetPath}`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${accessToken}`,
        'X-PARTNER-ID': this.clientId,
        'X-EXTERNAL-ID': externalId,
        'X-TIMESTAMP': timestamp,
        'X-SIGNATURE': signature,
        'CHANNEL-ID': 'H2H'
      },
      body: minified,
    });

    return await response.json();
  }
}

Common Pitfalls to Avoid

Anti-PatternIssueSolution
Using HMAC-SHA512 for DOKU Checkout401 Unauthorized / Invalid SignatureDOKU Checkout uses Non-SNAP HMAC-SHA256 with body Digest.
Using HMAC-SHA256 for SNAP BI Direct401 UnauthorizedSNAP BI transactional endpoints strictly require HMAC-SHA512 with lowercase hex SHA-256 body hash.
Forgetting CHANNEL-ID: H2H in SNAPBad requestSNAP BI Direct host-to-host APIs require CHANNEL-ID: H2H header.
Inverting Request-Target in WebhookSignature validation failsFor incoming webhooks, Request-Target is the merchant's endpoint path (e.g., /api/webhooks/doku/checkout).
OVO Push timeout too shortpremature failureOVO push payments require up to 70 seconds client timeout while the user confirms on mobile.
Non-atomic database updatesRace condition double top-upAlways guard webhook fulfillments with atomic SQL updates (WHERE status = 'PENDING').

Sovereign Execution, Token Efficiency & Invariants

DimensionSovereign Mandate & Deterministic Contract
Frontier Model CascadeHigh Fast / High (Grok 4.7 High Fast, Claude Sonnet 5.5 High, Gemini 4 Pro)
Availability FallbackGemini 4 Pro -> Gemini 3.8 Flash; Claude Opus 5.5 -> Claude Opus 4.6; Grok 4.7 -> Grok 4.6 High Fast (Zero unhandled missing-model errors)
KV-Cache & Token ProtocolPin static instructions & schemas at prompt prefix (kv-cache-prefix-optimizer); pass surgical CONTEXT_MAP.md slices (<250 tokens/call) during Swarm Fan-Out
SaaT CLI & MCP DispatchCLI: vibes skill exec doku-payment-gateway <audit|eval|verify|generate|blueprint> / MCP: vibes_skill_dispatch, vibes_critic_validate, vibes_self_heal, vibes_eval_sandbox, vibes_verify_invariants
NFR & Anti-Slop InvariantsZero OWASP Top 10 vectors, 0 hardcoded secrets, >= 90% branch coverage on domain logic, 0 Anti-Slop violations; 100% complete zero-placeholder output verified via node scripts/check-anti-slop.js --strict


Bahasa Indonesia

Integrasi Orkestrasi

  • Pembayaran & Routing Multi-Gateway: 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 & Idempotensi Atomik: database-orm-expert, saas-multi-tenant
  • Keamanan & Kriptografi Pasca-Kuantum: post-quantum-crypto-migrator, zero-trust-secret-vault, autonomous-red-teamer
  • Pemrosesan Asinkron & Observabilitas: async-queue-temporal-expert, data-telemetry-expert
  • Siklus Hidup & Tata Kelola: brainstorming, zero-to-prod-orchestrator, session-memory-manager, anti-slop

Deskripsi

Panduan ahli untuk mengintegrasikan DOKU Payment Gateway berdasarkan dokumentasi resmi DOKU Developers Portal. DOKU menyediakan 2 model integrasi utama:

  1. DOKU Checkout (/checkout/v1/payment): Halaman pembayaran hosted atau modal pop-up overlay (jokul-checkout-1.0.0.js). Cara termudah dan tercepat untuk menerima seluruh metode pembayaran (Virtual Account, Kartu Kredit, QRIS, E-Wallet, Indomaret/Alfamart, Paylater, Direct Debit) dalam satu kali integrasi. Menggunakan tanda tangan Non-SNAP HMAC-SHA256 dengan komponen Digest.
  2. Direct API:
    • Standar SNAP BI (Host-to-Host): Standar Bank Indonesia untuk integrasi perbankan langsung (B2B Access Token via RSA Asimetrik, transaksi via HMAC-SHA512 untuk Direct VA, Direct QRIS, dan Direct Debit).
    • Direct API Non-SNAP: Endpoint khusus untuk Kartu Kredit (/credit-card/v1/payment-page) dengan 3DS kustom dan OVO Push Payment (/ovo-emoney/v1/payment) langsung ke ponsel pengguna.

Perbandingan Model Integrasi (Checkout vs Direct API)

KebutuhanRekomendasi SolusiAlasan
E-commerce, SaaS, StarterDOKU Checkout1 API mengaktifkan semua kanal pembayaran sekaligus tanpa membangun UI per bank.
In-App Native Banking UIDirect API SNAP BIMemungkinkan merchant menampilkan nomor Virtual Account atau QRIS langsung di dalam aplikasi tanpa redirect.
Non-PCI DSS Card FormCredit Card Payment PageHalaman pembayaran kartu dengan 3DS aman tanpa beban audit sertifikasi PCI DSS.
Push Payment E-WalletOVO Push PaymentLangsung memicu prompt bayar di aplikasi OVO pelanggan menggunakan nomor ponsel (timeout 70 detik).

🚨 Simulator Sandbox DOKU

  • URL Simulator: https://sandbox.doku.com/gtw-config-v2/simulator
  • QRIS Simulator: https://sandbox.doku.com/qris-simulator/ Gunakan simulator resmi di atas untuk menguji transaksi Virtual Account dan QRIS dalam mode Sandbox sebelum deployment ke produksi.

Matriks Eksekusi Berdaulat, Efisiensi Token & Invarian

DimensiMandat Berdaulat & Kontrak Deterministik
Kaskade Model FrontierHigh Fast / High (Grok 4.7 High Fast, Claude Sonnet 5.5 High, Gemini 4 Pro)
Invarian Fallback KetersediaanGemini 4 Pro -> Gemini 3.8 Flash; Claude Opus 5.5 -> Claude Opus 4.6; Grok 4.7 -> Grok 4.6 High Fast (Bebas gagal saat model belum tersedia/kuota penuh)
Protokol Hemat Token & KV-CacheKunci instruksi & skema statis di prefix awal (kv-cache-prefix-optimizer); kirim potongan CONTEXT_MAP.md (<250 token/panggilan) saat Fan-Out
Eksekusi SaaT CLI & MCPCLI: vibes skill exec doku-payment-gateway <audit|eval|verify|generate|blueprint> / MCP: vibes_skill_dispatch, vibes_critic_validate, vibes_self_heal, vibes_eval_sandbox, vibes_verify_invariants
Invarian NFR & Anti-SlopNol celah OWASP Top 10, 0 kredensial hardcoded, cakupan pengujian >= 90% pada logika domain, 0 pelanggaran Anti-Slop; kode 100% tuntas tanpa placeholder diverifikasi melalui node scripts/check-anti-slop.js --strict

Frequently asked questions

What does the Doku Payment Gateway AI skill do?

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

Why use Doku Payment Gateway on TypingMind?

Because you install it once and use it with any model. Doku Payment Gateway is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Doku Payment Gateway in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/roedyrustam/vibes-plug/tree/main/skills/doku-payment-gateway. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Doku Payment Gateway?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Doku Payment Gateway?

As many as you like. As long as a model supports skills, you can use Doku Payment Gateway with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Doku Payment Gateway AI skill free?

Yes. It is published on GitHub by roedyrustam under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇