mcpField
P
paystack-setup

paystack-setup

github.com/rexedge开发167 次安装34 周前更新
代码仓库

关于 paystack-setup

paystack-setup 是一项技能,帮助 TypeScript/JavaScript 服务端应用配置 Paystack API 客户端与环境变量。它涵盖请求认证、分页、金额子单位换算和密钥安全实践。

主要功能

  1. 01配置 Paystack API 客户端
  2. 02管理服务端与公开密钥
  3. 03处理分页请求
  4. 04换算金额与货币子单位
  5. 05处理 API 错误
  6. 06遵循密钥与交易安全实践

适用场景

  1. 01在服务端发起 Paystack API 请求
  2. 02分页读取交易列表
  3. 03将展示金额转换为子单位
  4. 04验证交易并处理 API 错误

安装

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

$npx skills add https://github.com/rexedge/paystack --skill paystack-setup

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

详细介绍

Paystack 设置

为 TypeScript/JavaScript 服务端应用设置基础的 Paystack API 客户端和环境配置。

API 基础信息

属性值
基础 URLhttps://api.paystack.co
身份验证标头Authorization: Bearer SECRET_KEY
内容类型application/json
响应格式{ status: boolean, message: string, data: object }
金额单位货币的次级单位(显示金额 × 100)
交易 ID无符号 64 位整数——在 TypeScript 中使用 string

支持的货币和次级单位

货币代码次级单位倍数
尼日利亚奈拉NGNkobo×100
美元USDcent×100
加纳塞地GHSpesewa×100
南非兰特ZARcent×100
肯尼亚先令KEScent×100
西非法郎XOF—×100
埃及镑EGPpiaster×100
卢旺达法郎RWF—×100

环境变量

创建 .env 文件(Next.js 项目使用 .env.local):

PAYSTACK_SECRET_KEY=sk_test_xxxxx        # Server-side only, NEVER expose to client
NEXT_PUBLIC_PAYSTACK_PUBLIC_KEY=pk_test_xxxxx  # Safe for client-side (Popup/InlineJS)

密钥(sk_*)绝不能出现在客户端代码、浏览器包或公开代码仓库中。公钥(pk_*)仅可安全地用于前端的 Paystack Popup/InlineJS。

测试密钥以 sk_test_ / pk_test_ 开头。正式密钥以 sk_live_ / pk_live_ 开头。请在 Paystack Dashboard 的 Settings → API Keys & Webhooks 下获取这些密钥。

安装依赖

# For client-side Popup/InlineJS checkout
npm install @paystack/inline-js

# Or with pnpm / yarn
pnpm add @paystack/inline-js
yarn add @paystack/inline-js

无需服务端 SDK——使用内置的 fetch API 和下方的辅助函数即可。

TypeScript API 客户端辅助函数

创建一个可复用、类型安全的 Paystack 客户端。所有其他 Paystack 技能都依赖此模式:

// lib/paystack.ts
const PAYSTACK_SECRET_KEY = process.env.PAYSTACK_SECRET_KEY;

if (!PAYSTACK_SECRET_KEY) {
  throw new Error("PAYSTACK_SECRET_KEY is not set in environment variables");
}

export interface PaystackResponse<T = unknown> {
  status: boolean;
  message: string;
  data: T;
}

export interface PaystackListResponse<T = unknown> {
  status: boolean;
  message: string;
  data: T[];
  meta: {
    total: number;
    skipped: number;
    perPage: number;
    page: number;
    pageCount: number;
  };
}

export class PaystackError extends Error {
  constructor(
    message: string,
    public statusCode: number,
    public response?: unknown
  ) {
    super(message);
    this.name = "PaystackError";
  }
}

export async function paystackRequest<T>(
  endpoint: string,
  options: RequestInit = {}
): Promise<PaystackResponse<T>> {
  const url = `https://api.paystack.co${endpoint}`;

  const response = await fetch(url, {
    ...options,
    headers: {
      Authorization: `Bearer ${PAYSTACK_SECRET_KEY}`,
      "Content-Type": "application/json",
      ...options.headers,
    },
  });

  const data = await response.json();

  if (!response.ok) {
    throw new PaystackError(
      data.message || `Paystack API error: ${response.status}`,
      response.status,
      data
    );
  }

  return data as PaystackResponse<T>;
}

分页

所有列表端点都接受 perPage(默认值:50,最大值:100)和 page(默认值:1)作为查询参数。响应包含一个 meta 对象:

{
  "meta": {
    "total": 243,
    "skipped": 0,
    "perPage": 50,
    "page": 1,
    "pageCount": 5
  }
}

按如下方式构建分页查询:

const params = new URLSearchParams({
  perPage: "20",
  page: "2",
  from: "2024-01-01T00:00:00.000Z",
  to: "2024-12-31T23:59:59.000Z",
});
const result = await paystackRequest<Transaction[]>(`/transaction?${params}`);

金额转换

发送给 Paystack 前,务必将显示金额转换为次级单位;显示时再转换回来:

// Display → Paystack (multiply by 100)
const amountInKobo = Math.round(amountInNaira * 100);

// Paystack → Display (divide by 100)
const amountInNaira = amountInKobo / 100;

使用 Math.round() 避免浮点数问题,例如 19.99 * 100 = 1998.9999999999998。

HTTP 方法

方法用途
POST创建资源、发起操作
GET获取、列出、验证资源
PUT更新资源
DELETE停用或移除资源

错误处理

使用 try/catch 包装 Paystack 调用,并处理 PaystackError 类:

import { paystackRequest, PaystackError } from "@/lib/paystack";

try {
  const result = await paystackRequest<Transaction>("/transaction/verify/ref_123");
} catch (error) {
  if (error instanceof PaystackError) {
    console.error(`Paystack error ${error.statusCode}: ${error.message}`);
    // Handle specific status codes
    if (error.statusCode === 400) { /* bad request / validation error */ }
    if (error.statusCode === 401) { /* invalid secret key */ }
    if (error.statusCode === 404) { /* resource not found */ }
  }
  throw error;
}

安全检查清单

  • 仅在环境变量中存储 PAYSTACK_SECRET_KEY,绝不写入代码
  • 将 .env 和 .env.local 添加到 .gitignore
  • 所有 Paystack API 调用都必须在服务端运行(API 路由、服务端操作、后端)
  • 所有回调和 webhook URL 都必须使用 HTTPS
  • 初始化交易前在服务端验证金额
  • 付款后务必在服务端验证交易状态,切勿仅信任客户端回调

评论

支持 Markdown