@miniduckco/stash
v0.1.7
Published
integrate payments. switch once.
Downloads
36
Readme
@miniduckco/stash
Integrate payments in under 15 minutes.
Install
npm install @miniduckco/stashGetting started
Start with the quickstart tutorial: docs/tutorials/quickstart.md.
Quick examples
Make a payment (Paystack)
import { createStash } from "@miniduckco/stash";
const stash = createStash({
provider: "paystack",
credentials: { secretKey: process.env.PAYSTACK_SECRET_KEY! },
});
const payment = await stash.payments.create({
amount: "25.00",
currency: "ZAR",
reference: "ORDER-100",
customer: { email: "[email protected]" },
urls: { returnUrl: "https://example.com/return" },
});
console.log(payment.redirectUrl);Make a payment (Ozow)
import { createStash } from "@miniduckco/stash";
const stash = createStash({
provider: "ozow",
credentials: {
siteCode: process.env.OZOW_SITE_CODE!,
apiKey: process.env.OZOW_API_KEY!,
privateKey: process.env.OZOW_PRIVATE_KEY!,
},
});
const payment = await stash.payments.create({
amount: "10.00",
currency: "ZAR",
reference: "ORDER-200",
customer: { email: "[email protected]" },
urls: { returnUrl: "https://example.com/return" },
});
console.log(payment.redirectUrl);Make a payment (Payfast)
import { createStash } from "@miniduckco/stash";
const stash = createStash({
provider: "payfast",
credentials: {
merchantId: process.env.PAYFAST_MERCHANT_ID!,
merchantKey: process.env.PAYFAST_MERCHANT_KEY!,
passphrase: process.env.PAYFAST_PASSPHRASE,
},
});
const payment = await stash.payments.create({
amount: "10.00",
currency: "ZAR",
reference: "ORDER-300",
customer: { email: "[email protected]" },
urls: { returnUrl: "https://example.com/return" },
});
console.log(payment.redirectUrl);Create a subscription (Paystack)
const plan = await stash.subscriptions.plans.create({
name: "Monthly Retainer",
interval: "monthly",
amount: "5000.00",
});
const subscription = await stash.subscriptions.create({
customer: "CUS_xxxxxxxxxx",
plan: plan.planCode,
});
console.log(subscription.status);Docs (Diataxis)
- Tutorials:
docs/tutorials/quickstart.md - How-to guides:
docs/how-to/README.md - Reference:
docs/reference/api.md - Explanation:
docs/explanation/architecture.md - Skills quick reference:
doc/skill.md
Examples
Runnable examples live in examples/:
- Index:
examples/README.md
Subscriptions (Paystack)
Subscriptions let you create recurring billing in Paystack using plans and subscriptions.
Create a plan
import { createStash } from "@miniduckco/stash";
const stash = createStash({
provider: "paystack",
credentials: { secretKey: process.env.PAYSTACK_SECRET_KEY! },
});
const plan = await stash.subscriptions.plans.create({
name: "Monthly Retainer",
interval: "monthly",
amount: "5000.00",
amountUnit: "major",
currency: "ZAR",
invoiceLimit: 6,
});
console.log(plan.planCode);Create a subscription
const subscription = await stash.subscriptions.create({
customer: "CUS_xxxxxxxxxx",
plan: "PLN_xxxxxxxxxx",
authorization: "AUTH_xxxxxxxxxx",
startDate: "2026-04-01T00:00:00.000Z",
});
console.log(subscription.subscriptionCode, subscription.status);Webhook events
const parsed = stash.webhooks.parse({
rawBody,
headers,
});
if (parsed.event.type === "subscription.created") {
const { subscriptionCode, customerCode, planCode } = parsed.event.data;
}
if (parsed.event.type === "invoice.payment_failed") {
const { invoiceCode, subscriptionCode, amount, currency } = parsed.event.data;
}Full example: examples/subscriptions-paystack.ts.
Observability
Structured logging (opt-in) emits canonical events with correlation IDs and safe metadata. See Structured logging.
Site (SvelteKit)
The landing page + docs site lives in site/ and renders markdown directly from docs/.
Local dev:
npm install --prefix site
npm run dev --prefix site -- --host 0.0.0.0 --port 5173Docker preview:
docker build -t stash-site .
docker run --rm -p 5173:5173 stash-siteProviders and operations
Providers
- [x] Ozow
- [x] Payfast
- [x] Paystack
- [ ] Paygate
- [ ] Peach
Supported operations
- [x] payments.create
- [x] payments.verify (Ozow, Paystack; Payfast unsupported)
- [x] webhooks.parse
- [x] subscriptions.plans.create (Paystack)
- [x] subscriptions.create (Paystack)
Notes:
- Ozow hash excludes
CustomerCellphoneNumber,Token, andGenerateShortUrl. - Ozow
AllowVariableAmount=falseis excluded from the hash. - Payfast signature excludes
setupand requires uppercase URL encoding. - Paystack subscriptions emit subscription + invoice webhook events.
