Skip to content
Deployment
Skill

/pinme-uniwebpay

Use when generating, modifying, or reviewing PinMe Worker (Cloudflare Worker TypeScript) code that accepts payments through UniwebPay — payment links, products/prices, checkout sessions, payment status reads, refunds, subscriptions, or handling UniwebPay webhooks with

From plugin
pinme
3.7k7 skills
Install
$ npx -y skills add glitternetwork/pinme --skill pinme-uniwebpay --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/pinme-uniwebpay

Context preview

The summary Claude sees to decide when to auto-load this skill.

Use when generating, modifying, or reviewing PinMe Worker (Cloudflare Worker TypeScript) code that accepts payments through UniwebPay — payment links, products/prices, checkout sessions, payment status reads, refunds, subscriptions, or handling UniwebPay webhooks with

SKILL.md

pinme-uniwebpay.SKILL.md
name: pinme-uniwebpay
description: Use when generating, modifying, or reviewing PinMe Worker (Cloudflare Worker TypeScript) code that accepts payments through UniwebPay — payment links, products/prices, checkout sessions, payment status reads, refunds, subscriptions, or handling UniwebPay webhooks with @uniwebpay/sdk in a PinMe project.

PinMe UniwebPay Payment Integration

Guides writing payment services in a PinMe Worker (Cloudflare Worker TypeScript) that call UniwebPay directly through `@uniwebpay/sdk`.

Core model: PinMe provisions the UniwebPay wallet and keys per **PinMe user** (not per project) and injects `UNIWEB_*` environment bindings at Worker deploy time; Worker code calls UniwebPay **directly with the SDK** — it does not go through PinMe payment proxy routes, and it must not call the legacy VibeCash APIs.

Environment Binding Contract

export interface Env {
  UNIWEB_SECRET: string;           // PinMe-provisioned sk_server_ key (server-side only)
  UNIWEB_WEBHOOK_SECRET?: string;  // wallet-level whsec_, used to verify webhook signatures
  UNIWEB_API_URL?: string;         // UniwebPay API endpoint override (default https://apiskill.uniwebpay.com)
  UNIWEB_PAY_URL?: string;         // UniwebPay checkout host override (default https://skill.uniwebpay.com)
  UNIWEB_WALLET_ID?: string;       // user-level wallet id (wal_), diagnostics/reconciliation only
  WORKER_URL?: string;             // this project's public URL: https://{projectName}.{platform api domain}
  PROJECT_NAME?: string;           // PinMe project name
  DB?: D1Database;                 // project D1 (if enabled)
}

Injection rules (metadata is rebuilt server-side by PinMe at deploy time; client-supplied bindings are ignored):

  • The `UNIWEB_*` bindings are injected only after the user's UniwebPay credentials have been provisioned. Newly created projects are provisioned automatically and get them immediately; **existing projects must be redeployed after enabling UniwebPay or rotating keys** to pick up new bindings.
  • `WORKER_URL`, `PROJECT_NAME`, `API_KEY`, `DB` and other base bindings are injected on every deploy, independent of UniwebPay.
  • All projects owned by the same PinMe user share one wallet, one `sk_server_`, and one `whsec_`.
  • PinMe never gives the full wallet secret (`sk_live_`) to a Worker. Do not ask the user for it, and do not put it in code, `wrangler.toml`, `.dev.vars`, responses, logs, D1, or frontend bundles.
  • If `UNIWEB_SECRET` is missing at runtime, the user has not enabled UniwebPay or has not redeployed — tell the user to enable it and redeploy; never fabricate a value.

SDK Client

Always instantiate on the server side (the Worker); the SDK throws when run in a browser:

import Uniweb from "@uniwebpay/sdk";

function uniwebClient(env: Env): Uniweb {
  return new Uniweb(env.UNIWEB_SECRET, {
    baseUrl: env.UNIWEB_API_URL,
    payUrl: env.UNIWEB_PAY_URL,
  });
}
  • The constructor's first positional argument is the key (must have an `sk_server_` or `sk_live_` prefix); the second is optional options: `{ baseUrl?, payUrl?, timeout? (default 30s), maxRetries? (default 2) }`.
  • The SDK auto-retries only GET/DELETE on 429/5xx; POST/PATCH are never retried (avoids duplicate charges).
  • Install `@uniwebpay/sdk` only when Worker code imports it; pick the package manager from the project's existing lockfile.

Choosing an Integration Path

| Scenario | Approach | Returns | |------|------|------| | Fixed-amount one-time collection | `uniweb.links.create(...)` | Permanent, reusable `/p/` link (one-time payments only) | | Stable product catalog | `products.create` + `prices.create` once, store the `priceId` | Price carries a permanent `paymentUrl` (`/buy/` link) | | Dynamic cart/order | Reuse or create a price, then `uniweb.checkout.create(...)` | `session.url` — **one-time, expires in 24 hours** | | Subscriptions | Recurring price + `checkout.create({ mode: "subscription" })` or `subscriptions.create` | Same as above | | Server-side payment status checks | `payments.get / list` | Server routes only |

Amounts are always **integer minor units** (cents). Default currency convention is `SGD` unless the app has a stronger existing convention. Do not create a new product/price on every page view — create stable catalog items once and persist the `priceId`.

Payment Methods and Currency Rules

| Method | Supported currencies | |------|---------| | `card` | SGD, USD, EUR, GBP, JPY, CNY, HKD, AUD, MYR, THB (minimum 10 minor units) | | `wechat` | SGD only | | `alipay` | SGD only | | `paynow` | SGD only |

  • The QR methods (wechat/alipay/paynow) **all support SGD only** — never generate "CNY via WeChat/Alipay" code.
  • Subscriptions (recurring / `mode: "subscription"`) use `card` only.
  • When `paymentMethodTypes` is omitted, the server picks sensible defaults for the currency; when passed explicitly, validate user input against the table above first.

SDK Surface Quick Reference

The surface below is verified against source. All parameter fields are camelCase (`priceId`, `webhookUrl`, `startingAfter`, …); the SDK handles wire-level conversion itself. `list()` returns `{ data: T[], hasMore: boolean }`; `listAll()` is an async generator available on products, prices, payments, customers, subscriptions, and links (not on checkout or refunds).

Products (`webhookUrl` is the per-product callback override):

await uniweb.products.create({ name, description?, webhookUrl?, metadata? });
await uniweb.products.list({ limit?, startingAfter? });
await uniweb.products.get(productId);
await uniweb.products.update(productId, { name?, description?, webhookUrl?, active?, metadata? });
await uniweb.products.del(productId);
for await (const product of uniweb.products.listAll()) {}

Prices (the returned price carries a permanent `paymentUrl`; `deactivate` takes it off sale):

await uniweb.prices.create({
  productId,
  amount,        // in
Read more
Ships withpinme

PinMe is a zero-config deployment CLI focused on one-command creation and deployment for full-stack projects. It lets you quickly set up and launch a complete project with an integrated frontend, Worker backend, and database, without tedious configuration.

Get the whole plugin
Stats
3,742
Stars
276
Forks
Active
Maintenance
TypeScript
Language
MIT
License
3d ago
Last commit
1y ago
Created

Repo: glitternetwork/pinme

Other skills on pinme.