mcpField
H
hitpay

hitpay

github.com/hit-pay开发0131 次安装42 周前更新
代码仓库

关于 hitpay

hitpay 是面向 APAC 企业的 HitPay 集成技能,适用于使用 JavaScript 或 TypeScript 的 Next.js 项目。内容涵盖卡片支付、二维码支付、Webhook、状态查询和退款。

主要功能

  1. 01卡片支付跳转结账
  2. 02嵌入式二维码支付
  3. 03支付方式选择
  4. 04Webhook 签名验证
  5. 05查询支付状态与退款

适用场景

  1. 01为 Next.js 商店添加托管卡片结账
  2. 02在网站提供二维码支付
  3. 03通过 Webhook 确认付款
  4. 04查询支付状态或发起退款

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/hit-pay/agent-skills --skill hitpay

安装后在 Claude Code 中输入/hitpay确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
payment-request-api.md
refunds.md
webhook-events.md
scripts/
verify-webhook.sh

详细介绍

HitPay 集成

面向使用 Next.js 和 JavaScript/TypeScript 的亚太地区企业的支付网关集成。支持通过重定向进行银行卡支付,以及通过嵌入式二维码进行二维码支付(PayNow、GrabPay 等)。

适用场景

在以下情况下参考此技能:

  • 集成 HitPay 支付网关
  • 创建支付结账流程
  • 实现二维码支付(PayNow、GrabPay、ShopeePay)
  • 处理支付 Webhook
  • 处理退款

第 1 步:确定支付方式

询问客户希望支持哪些支付方式:

仅银行卡支付
  • card(Visa、Mastercard、Amex)
仅二维码支付
  • paynow_online(新加坡)
  • grabpay_direct
  • shopee_pay
  • wechat
  • alipay
  • fpx(马来西亚)
  • promptpay(泰国)
  • truemoney(泰国)
  • vietqr(越南)
  • qris(印度尼西亚)
  • upi(印度)
  • gcash(菲律宾)

第 2 步:选择前端方案

支付方式推荐的前端方案
仅银行卡支付重定向到 HitPay 结账页面
仅二维码支付在你的网站上嵌入二维码
银行卡和二维码支付先选择支付方式,再进入相应流程

API 基础信息

环境基础 URL
沙盒https://api.sandbox.hit-pay.com
生产环境https://api.hit-pay.com
身份验证
const headers = {
  'X-BUSINESS-API-KEY': process.env.HITPAY_API_KEY,
  'Content-Type': 'application/json',
};

在 HitPay 控制面板中,前往 Settings → Payment Gateway → API Keys 获取 API 密钥。

前端方案 A:重定向(银行卡)

适用于银行卡支付,或希望由 HitPay 处理完整结账界面的场景。

流程
  1. 后端创建支付请求
  2. 前端重定向到 response.url
  3. 客户在 HitPay 托管页面上付款
  4. 客户返回你的 redirect_url
  5. 后端通过 Webhook 确认付款
Next.js API 路由
// 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>;
}

前端方案 B:嵌入式二维码

适用于二维码支付,客户可留在你的网站上完成付款。

流程
  1. 后端创建支付请求,并设置 generate_qr: true
  2. 前端根据 response.qr_code_data 渲染二维码
  3. 客户使用支付应用扫描二维码
  4. 前端轮询状态或监听 Webhook
  5. 后端通过 Webhook 确认付款
Next.js API 路由
// 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>
  );
}

前端方案 C:支付方式选择器

适用于同时支持银行卡和二维码支付的场景。

前端组件
// 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 处理

处理 Webhook 前,务必验证签名。详情请参阅 references/webhook-events.md。

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

检查支付状态

完整 API 参考请参阅 references/payment-request-api.md。

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

退款

详情请参阅 references/refunds.md。

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

环境变量

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

测试卡(沙盒)

结果卡号有效期CVC
成功4242 4242 4242 4242任意未来日期任意 3 位数字
拒绝4000 0000 0000 0002任意未来日期任意 3 位数字

资源

评论

支持 Markdown