From hitpay
Integrate HitPay payment gateway for online payments in Next.js and JS/TS applications. Use when user says "Add HitPay", "HitPay checkout", "HitPay payments", "PayNow integration", "HitPay integration", "payment gateway", or "accept payments".
How this skill is triggered — by the user, by Claude, or both
Slash command
/hitpay:payment-integrationThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Payment gateway integration for APAC businesses using Next.js and JavaScript/TypeScript. Supports card payments via redirect, QR-based payments (PayNow, GrabPay, etc.) via embedded QR codes, and HitPay Drop-In UI for an all-in-one checkout.
Payment gateway integration for APAC businesses using Next.js and JavaScript/TypeScript. Supports card payments via redirect, QR-based payments (PayNow, GrabPay, etc.) via embedded QR codes, and HitPay Drop-In UI for an all-in-one checkout.
Reference this skill when:
Need the Drop-In UI? For HitPay.js embedded checkout modal, see the drop-in-ui skill. Operating payments via MCP tools? For provider-currency mapping and QR operations, use the payment-methods skill.
Ask which payment methods the developer wants to support:
card (Visa, Mastercard, Amex)paynow_online (Singapore)grabpay_directshopee_paywechatalipayfpx (Malaysia)promptpay (Thailand)truemoney (Thailand)vietqr (Vietnam)qris (Indonesia)upi (India)gcash (Philippines)| Payment Methods | Recommended Frontend |
|---|---|
| Card only | Option A: Redirect to HitPay checkout |
| QR only | Option B: Embedded QR on your site |
| Both card + QR | Option C: Payment method selector |
| Full checkout experience | Option D: HitPay Drop-In UI (see drop-in-ui skill) |
| Environment | Base URL |
|---|---|
| Sandbox | https://api.sandbox.hit-pay.com |
| Production | https://api.hit-pay.com |
const headers = {
'X-BUSINESS-API-KEY': process.env.HITPAY_API_KEY,
'Content-Type': 'application/json',
};
Get API keys from Settings > Payment Gateway > API Keys in your HitPay dashboard.
Best for card payments or when you want HitPay to handle the full checkout UI.
response.urlredirect_url// app/api/payments/create/route.ts
import { NextResponse } from 'next/server';
export async function POST(request: Request) {
const { amount, currency, orderId } = await request.json();
const response = await fetch('https://api.sandbox.hit-pay.com/v1/payment-requests', {
method: 'POST',
headers: {
'X-BUSINESS-API-KEY': process.env.HITPAY_API_KEY!,
'Content-Type': 'application/json',
},
body: JSON.stringify({
amount,
currency,
payment_methods: ['card'],
reference_number: orderId,
redirect_url: `${process.env.NEXT_PUBLIC_APP_URL}/payment/complete`,
webhook: `${process.env.NEXT_PUBLIC_APP_URL}/api/webhooks/hitpay`,
}),
});
const data = await response.json();
return NextResponse.json({ url: data.url, paymentRequestId: data.id });
}
// components/CheckoutButton.tsx
'use client';
export function CheckoutButton({ amount, currency, orderId }: Props) {
const handleCheckout = async () => {
const response = await fetch('/api/payments/create', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ amount, currency, orderId }),
});
const { url } = await response.json();
window.location.href = url; // Redirect to HitPay
};
return <button onClick={handleCheckout}>Pay with Card</button>;
}
Best for QR-based payments where customer stays on your site.
generate_qr: trueresponse.qr_code_data// app/api/payments/create-qr/route.ts
import { NextResponse } from 'next/server';
export async function POST(request: Request) {
const { amount, currency, orderId, paymentMethod } = await request.json();
const response = await fetch('https://api.sandbox.hit-pay.com/v1/payment-requests', {
method: 'POST',
headers: {
'X-BUSINESS-API-KEY': process.env.HITPAY_API_KEY!,
'Content-Type': 'application/json',
},
body: JSON.stringify({
amount,
currency,
payment_methods: [paymentMethod],
generate_qr: true,
reference_number: orderId,
webhook: `${process.env.NEXT_PUBLIC_APP_URL}/api/webhooks/hitpay`,
}),
});
const data = await response.json();
return NextResponse.json({
paymentRequestId: data.id,
qrCodeData: data.qr_code_data,
});
}
// components/QRPayment.tsx
'use client';
import { useEffect, useRef } from 'react';
import QRCode from 'qrcode';
export function QRPayment({ amount, currency, orderId, paymentMethod }: Props) {
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
const createQR = async () => {
const response = await fetch('/api/payments/create-qr', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ amount, currency, orderId, paymentMethod }),
});
const { qrCodeData } = await response.json();
if (canvasRef.current && qrCodeData) {
await QRCode.toCanvas(canvasRef.current, qrCodeData, { width: 256 });
}
};
createQR();
}, [amount, currency, orderId, paymentMethod]);
return (
<div>
<canvas ref={canvasRef} />
<p>Scan with your payment app</p>
</div>
);
}
Best for supporting both cards and QR methods.
// components/PaymentMethodSelector.tsx
'use client';
import { useState } from 'react';
import { QRPayment } from './QRPayment';
const PAYMENT_METHODS = [
{ id: 'card', label: 'Credit/Debit Card', type: 'redirect' },
{ id: 'paynow_online', label: 'PayNow', type: 'qr' },
{ id: 'grabpay_direct', label: 'GrabPay', type: 'qr' },
{ id: 'shopee_pay', label: 'ShopeePay', type: 'qr' },
];
export function PaymentMethodSelector({ amount, currency, orderId }: Props) {
const [selected, setSelected] = useState<string | null>(null);
const handlePayment = async (method: typeof PAYMENT_METHODS[0]) => {
if (method.type === 'redirect') {
const response = await fetch('/api/payments/create', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ amount, currency, orderId }),
});
const { url } = await response.json();
window.location.href = url;
} else {
setSelected(method.id);
}
};
if (selected) {
return (
<QRPayment
amount={amount}
currency={currency}
orderId={orderId}
paymentMethod={selected}
/>
);
}
return (
<div>
<h3>Select Payment Method</h3>
{PAYMENT_METHODS.map((method) => (
<button key={method.id} onClick={() => handlePayment(method)}>
{method.label}
</button>
))}
</div>
);
}
Always verify webhook signatures before processing. See the webhook-handler skill for full details.
// app/api/webhooks/hitpay/route.ts
import { NextResponse } from 'next/server';
import crypto from 'crypto';
export async function POST(request: Request) {
const body = await request.text();
const signature = request.headers.get('Hitpay-Signature');
const expectedSignature = crypto
.createHmac('sha256', process.env.HITPAY_SALT!)
.update(body)
.digest('hex');
if (signature !== expectedSignature) {
return NextResponse.json({ error: 'Invalid signature' }, { status: 401 });
}
const payload = JSON.parse(body);
if (payload.status === 'completed') {
await markOrderAsPaid(payload.reference_number);
}
return NextResponse.json({ received: true });
}
See references/payment-request-api.md for the full API reference.
// app/api/payments/[id]/route.ts
export async function GET(
request: Request,
{ params }: { params: { id: string } }
) {
const response = await fetch(
`https://api.sandbox.hit-pay.com/v1/payment-requests/${params.id}`,
{
headers: {
'X-BUSINESS-API-KEY': process.env.HITPAY_API_KEY!,
},
}
);
const data = await response.json();
return NextResponse.json(data);
}
# .env.local
HITPAY_API_KEY=your_api_key
HITPAY_SALT=your_webhook_salt
NEXT_PUBLIC_APP_URL=http://localhost:3000
| Result | Number | Expiry | CVC |
|---|---|---|---|
| Success | 4242 4242 4242 4242 | Any future | Any 3 digits |
| Declined | 4000 0000 0000 0002 | Any future | Any 3 digits |
npx claudepluginhub hit-pay/claude-code-plugin --plugin hitpayGuides developers through integrating Paymob payment gateway. Covers Intention API, Unified Checkout, Pixel SDK, HMAC validation, webhooks, subscriptions, and regional endpoints for Egypt, KSA, UAE, Oman.
Integrates Stripe, PayPal, and Square for checkout flows, subscriptions, webhooks, and PCI compliance. Use when implementing payment or billing features.
Integrates PAYUNi UPP payment gateway using AES-256 encryption, form submission, order creation, and callback handling for Laravel, Next.js, Django, Express, and similar frameworks.