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", "HitPay webhook", "HitPay QR code", "PayNow integration", or "HitPay integration".

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "hitpay" with this command: npx skills add hit-pay/agent-skills/hit-pay-agent-skills-hitpay

HitPay Integration

Payment gateway integration for APAC businesses using Next.js and JavaScript/TypeScript. Supports card payments via redirect and QR-based payments (PayNow, GrabPay, etc.) via embedded QR codes.

When to Apply

Reference this skill when:

  • Integrating HitPay payment gateway
  • Creating payment checkout flows
  • Implementing QR code payments (PayNow, GrabPay, ShopeePay)
  • Handling payment webhooks
  • Processing refunds

Step 1: Determine Payment Methods

Ask which payment methods the customer wants to support:

Card-Only Methods

  • card (Visa, Mastercard, Amex)

QR-Only Methods

  • paynow_online (Singapore)
  • grabpay_direct
  • shopee_pay
  • wechat
  • alipay
  • fpx (Malaysia)
  • promptpay (Thailand)
  • truemoney (Thailand)
  • vietqr (Vietnam)
  • qris (Indonesia)
  • upi (India)
  • gcash (Philippines)

Step 2: Choose Frontend Approach

Payment MethodsRecommended Frontend
Card onlyRedirect to HitPay checkout
QR onlyEmbedded QR on your site
Both card + QRPayment method selector then appropriate flow

API Basics

EnvironmentBase URL
Sandboxhttps://api.sandbox.hit-pay.com
Productionhttps://api.hit-pay.com

Authentication

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.

Frontend Option A: Redirect (Cards)

Best for card payments or when you want HitPay to handle the full checkout UI.

Flow

  1. Backend creates payment request
  2. Frontend redirects to response.url
  3. Customer pays on HitPay hosted page
  4. Customer returns to your redirect_url
  5. Backend confirms via webhook

Next.js API Route

// 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 });
}

Frontend Component

// 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>;
}

Frontend Option B: Embedded QR Code

Best for QR-based payments where customer stays on your site.

Flow

  1. Backend creates payment request with generate_qr: true
  2. Frontend renders QR code from response.qr_code_data
  3. Customer scans with payment app
  4. Frontend polls for status or listens for webhook
  5. Backend confirms via webhook

Next.js API Route

// 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,
  });
}

Frontend Component

// 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>
  );
}

Frontend Option C: Payment Method Selector

Best for supporting both cards and QR methods.

Frontend Component

// 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>
  );
}

Webhook Handling

Always verify webhook signatures before processing. See references/webhook-events.md for 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');

  // Verify 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);

  // Process payment confirmation
  if (payload.status === 'completed') {
    // Mark order as paid
    await markOrderAsPaid(payload.reference_number);
  }

  return NextResponse.json({ received: true });
}

Checking Payment Status

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);
}

Refunds

See references/refunds.md for full details.

// app/api/payments/[id]/refund/route.ts
export async function POST(
  request: Request,
  { params }: { params: { id: string } }
) {
  const { amount } = await request.json();

  const response = await fetch(
    `https://api.sandbox.hit-pay.com/v1/payment-requests/${params.id}/refund`,
    {
      method: 'POST',
      headers: {
        'X-BUSINESS-API-KEY': process.env.HITPAY_API_KEY!,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ amount }),
    }
  );

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

Environment Variables

# .env.local
HITPAY_API_KEY=your_api_key
HITPAY_SALT=your_webhook_salt
NEXT_PUBLIC_APP_URL=http://localhost:3000

Test Cards (Sandbox)

ResultNumberExpiryCVC
Success4242 4242 4242 4242Any futureAny 3 digits
Declined4000 0000 0000 0002Any futureAny 3 digits

Resources

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

vercel-react-best-practices

React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.

Repository Source
23K212.7K
vercel
Coding

svelte5-best-practices

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

apify-actor-development

No summary provided by upstream source.

Repository SourceNeeds Review
-2.1K
apify