Client-only payment modal SDK for browser environments
npm install @ojire/pg-js-sdkA lightweight JavaScript SDK for integrating Ojire Payment Gateway into your web applications. This SDK provides a simple modal-based payment flow that works with any JavaScript framework or vanilla JS.
- Modal-based payment UI
- Support for multiple payment methods (QRIS, Virtual Account, Credit Card)
- Sandbox and Production environments
- TypeScript support
- Framework agnostic (works with React, Vue, Angular, or vanilla JS)
- Lightweight (~5KB gzipped)
``bash`
npm install @ojire/pg-js-sdk
`bash`
yarn add @ojire/pg-js-sdk
`html`
src="https://cdn.jsdelivr.net/npm/@ojire/pg-js-sdk@latest/dist/opg-sdk.umd.js"
data-client-key="pk_your_public_key_here"
data-sandbox="true"
>
Obtain your API keys from the Ojire Dashboard:
- Public Key (pk_...): Used in frontend to identify your merchantsk_...
- Secret Key (): Used in backend to create payment intents (never expose this in frontend!)
First, create a payment intent from your backend server:
`javascript
// Backend (Node.js example)
const response = await fetch('https://api.ojire.online/v1/payment-intents', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Secret-Key': 'sk_your_secret_key'
},
body: JSON.stringify({
amount: 100000,
currency: 'IDR',
merchantId: 'your_merchant_id',
customerId: 'customer_123',
description: 'Order #12345',
metadata: {
orderId: 'order_12345'
}
})
});
const paymentIntent = await response.json();
// Returns: { id, clientSecret, customerToken, ... }
`
#### Using Script Tag (Vanilla JS)
`html
src="https://cdn.jsdelivr.net/npm/@ojire/pg-js-sdk@latest/dist/opg-sdk.umd.js"
data-client-key="pk_your_public_key"
data-sandbox="true"
>
`
#### Using ES Modules
`javascript
import OPG from '@ojire/pg-js-sdk';
// Configure SDK
OPG.configure({
sandbox: true // Set to false for production
});
// Open payment modal
OPG.openPayment({
token: paymentIntent.customerToken,
clientSecret: paymentIntent.clientSecret,
paymentId: paymentIntent.id,
onSuccess: (result) => {
console.log('Payment successful!', result);
},
onPending: (result) => {
console.log('Payment pending', result);
},
onError: (result) => {
console.log('Payment failed', result);
}
});
`
Opens the payment modal.
#### Options
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| token | string | Yes | Customer token from payment intent |clientSecret
| | string | Yes | Client secret from payment intent |paymentId
| | string | Yes | Payment intent ID |sandbox
| | boolean | No | Override sandbox mode for this payment |onSuccess
| | function | No | Callback when payment succeeds |onPending
| | function | No | Callback when payment is pending |onError
| | function | No | Callback when payment fails |
#### Example
`javascript`
OPG.openPayment({
token: 'cust_token_xxx',
clientSecret: 'pi_secret_xxx',
paymentId: 'pi_xxx',
sandbox: true,
onSuccess: (result) => {
console.log('Transaction status:', result.transactionStatus);
console.log('Mapped status:', result.status);
console.log('Raw data:', result.rawData);
},
onPending: (result) => {
// Handle pending payment (e.g., waiting for bank transfer)
},
onError: (result) => {
// Handle failed payment
}
});
Programmatically closes the payment modal.
`javascript`
OPG.closePayment();
Returns true if the payment modal is currently open.
`javascript`
if (OPG.isPaymentOpen()) {
console.log('Modal is open');
}
Configures SDK settings.
`javascript`
OPG.configure({
sandbox: false // Set to true for sandbox, false for production
});
Returns true if SDK is in sandbox mode.
`javascript`
if (OPG.isSandbox()) {
console.log('Running in sandbox mode');
}
All callbacks receive a PaymentResult object:
`typescript`
interface PaymentResult {
transactionStatus: TransactionStatus;
status: 'success' | 'pending' | 'error';
rawData: Record
}
| Status | Mapped To | Description |
|--------|-----------|-------------|
| settlement | success | Payment completed |capture
| | success | Payment captured |pending
| | pending | Waiting for payment |challenge
| | pending | Needs verification |deny
| | error | Payment denied |cancel
| | error | Payment cancelled |expire
| | error | Payment expired |failure
| | error | Payment failed |
`tsx
import React, { useState } from 'react';
import OPG from '@ojire/pg-js-sdk';
import type { PaymentResult } from '@ojire/pg-js-sdk';
function CheckoutButton() {
const [loading, setLoading] = useState(false);
const [status, setStatus] = useState
const handlePayment = async () => {
setLoading(true);
try {
// Get payment intent from your backend
const response = await fetch('/api/create-payment-intent', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ amount: 100000 })
});
const paymentIntent = await response.json();
OPG.openPayment({
token: paymentIntent.customerToken,
clientSecret: paymentIntent.clientSecret,
paymentId: paymentIntent.id,
onSuccess: (result: PaymentResult) => {
setLoading(false);
setStatus('Payment successful!');
// Redirect or update UI
},
onPending: (result: PaymentResult) => {
setLoading(false);
setStatus('Payment pending. Please complete the payment.');
},
onError: (result: PaymentResult) => {
setLoading(false);
setStatus(Payment failed: ${result.transactionStatus});
}
});
} catch (error) {
setLoading(false);
setStatus('Failed to initialize payment');
}
};
return (
{status}
}export default CheckoutButton;
`
` {{ status }}vue
`
When using the CDN version, configure via data attributes:
`html`
src="https://cdn.jsdelivr.net/npm/@ojire/pg-js-sdk@latest/dist/opg-sdk.umd.js"
data-client-key="pk_your_public_key"
data-sandbox="true"
>
| Attribute | Description |
|-----------|-------------|
| data-client-key | Your public key (required) |data-sandbox
| | Set to "true" for sandbox, "false" for production |
`javascript
import OPG from '@ojire/pg-js-sdk';
OPG.configure({
sandbox: process.env.NODE_ENV !== 'production'
});
`
| Environment | API URL | Payment URL |
|-------------|---------|-------------|
| Sandbox | https://api-dev.ojire.online | https://pay-dev.ojire.online |https://api.ojire.online
| Production | | https://pay.ojire.online |
The SDK includes TypeScript definitions. Import types as needed:
`typescript`
import OPG, {
PaymentResult,
PaymentCallbacks,
OpenPaymentOptions,
TransactionStatus,
PaymentResultStatus
} from '@ojire/pg-js-sdk';
`javascript``
try {
OPG.openPayment({
token: paymentIntent.customerToken,
clientSecret: paymentIntent.clientSecret,
paymentId: paymentIntent.id,
onError: (result) => {
switch (result.transactionStatus) {
case 'expire':
alert('Payment expired. Please try again.');
break;
case 'cancel':
alert('Payment was cancelled.');
break;
case 'deny':
alert('Payment was denied. Please use a different payment method.');
break;
default:
alert('Payment failed. Please try again.');
}
}
});
} catch (error) {
// Handle SDK initialization errors
console.error('SDK Error:', error.message);
}
1. Never expose your Secret Key in frontend code
2. Always create payment intents on your backend
3. Validate payment status on your backend after receiving callbacks
4. Use HTTPS in production
5. Verify webhook signatures for server-to-server notifications
- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
- Mobile browsers (iOS Safari, Chrome for Android)
- Documentation: https://docs.ojire.online
- Email: support@ojire.online
- GitHub Issues: https://github.com/ojire-tech/opg-sdk/issues
MIT License - see LICENSE for details.