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.8k7 skills

Claude Code

$ npx -y skills add glitternetwork/pinme --skill pinme-uniwebpay --agent claude-code

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
@glitternetwork
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.

Stars on GitHub

Momentum

stars in total
3.8k
Star history of glitternetwork/pinme on GitHub, a chart by star-history.com

Other skills on pinme.

pinme-auth

pinme-auth

Use when a PinMe project (Worker TypeScript) needs to integrate user authentication — creating email/password users, verifying…

pinme-email

pinme-email

Use this skill when a PinMe project (Worker TypeScript) needs to integrate email sending (send_email). Guides AI to generate…

pinme-llm

pinme-llm

Use this skill when a PinMe project (Worker TypeScript) needs to call OpenRouter-backed LLM APIs, including models,…

pinme-r2

pinme-r2

Use when a PinMe Cloudflare Worker needs R2 object storage, including secure file or image upload, streaming download, metadata…

pinme-share

pinme-share

Use this skill when the user wants to share, publish, or upload a static result through PinMe, especially by generating a static…

pinme

pinme

Use this skill when the user mentions "pinme", or needs to upload files, store to IPFS, create/publish/deploy websites or…

More skills from other plugins.

configuring-horizon

configuring-horizon

Use this skill whenever the user mentions Horizon by name in a Laravel context. Covers the full Horizon lifecycle: installing…

coolify9d66k
@coollabsio@coollabsioInstall Skill
vercel-cli

vercel-cli

Guides deployment, configuration, and troubleshooting with the Vercel CLI. Use when operating Vercel projects or resources…

vercel11d16k
@vercel@vercelInstall Skill
skypilot

skypilot

Use when launching cloud VMs, Kubernetes pods, or Slurm jobs for GPU/TPU/CPU workloads, training or fine-tuning models on cloud…

@skypilot-org@skypilot-orgInstall Skill
mlx-serve

mlx-serve

Hook an app, game or script up to the local mlx-serve server for LLM chat, embeddings, image, speech, music, sound effect, video…

mlx-serve11d2.2k
@ddalcu@ddalcuInstall Skill

Questions about pinme-uniwebpay.

Which coding agents can use pinme-uniwebpay?
pinme-uniwebpay installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.