@kody/paypal
Read PayPal invoices and transactions, and send invoices or payouts with dry-run mutations.
AGENTS.md
116 lines · 3.5 KB · Markdown@kody/paypal — agent notes
Human setup and intent live in README.md. This file is for
agents: imports, smoke/dryRun execute snippets, and edge cases. Secrets by
name only — never paste client secret values. Do not disable live webhooks
or jobs.
Secrets
| Name | Purpose |
|---|---|
paypalClientId | REST app client ID; hosts api-m.paypal.com, api-m.sandbox.paypal.com |
paypalClientSecret | REST app client secret (same hosts) |
paypalClientId-<label> / paypalClientSecret-<label> | Extra account via account: "<label>" or explicit secret name fields |
Placeholder shape: {{secret:paypalClientId|scope=user}}.
Import paths
| Export | Import |
|---|---|
root dispatcher (default smoke-test) | kody:@kody/paypal |
| invoices | kody:@kody/paypal/invoices |
| transactions | kody:@kody/paypal/transactions |
| reimbursements | kody:@kody/paypal/reimbursements |
| payouts | kody:@kody/paypal/payouts |
| smoke-test | kody:@kody/paypal/smoke-test |
| scheduled-reimbursement-scan | kody:@kody/paypal/scheduled-reimbursement-scan |
Prefer static kody:@kody/paypal/... imports from execute. Do not lead with
packages.invoke. Root also re-exports helpers.
Smoke test (read-only)
Safe before credentials exist ({ ok: true, live: false } plus setup URLs).
With both secrets and host approval, lists a few invoices — no sends or money.
import smokeTest from 'kody:@kody/paypal/smoke-test'
export default async function main() {
return await smokeTest()
}Equivalent via root dispatcher:
import paypal from 'kody:@kody/paypal'
export default async function main() {
return await paypal({ action: 'smoke-test' })
}dryRun / confirm (mutations)
Pass dryRun: true on createInvoice, sendInvoice, and createPayout to
return { dryRun: true, method, path, body } without contacting PayPal.
sendInvoice, createInvoice({ send: true }), and createPayout also throw
unless confirm: true.
Recipients, item names, memos, and payout notes come from the call. This package has no default customer or invoice template.
import { sendInvoice } from 'kody:@kody/paypal/invoices'
import { createPayout } from 'kody:@kody/paypal/payouts'
export default async function main() {
const invoicePreview = await sendInvoice({
id: 'INV2-XXXX-XXXX-XXXX-XXXX',
dryRun: true,
})
const payoutPreview = await createPayout({
receiver: 'ada@example.com',
amount: '25.00',
note: 'Conference travel',
dryRun: true,
})
return { invoicePreview, payoutPreview }
}Live send only after explicit user approval of the exact invoice or payout:
import { sendInvoice } from 'kody:@kody/paypal/invoices'
export default async function main() {
return await sendInvoice({
id: 'INV2-XXXX-XXXX-XXXX-XXXX',
confirm: true,
})
}Jobs
reimbursement-scan→./scheduled-reimbursement-scan, cron0 9 * * 1UTC,enabled: falsein this listing.- Do not flip
enabledwithout an explicit operator request after fork. - Do not disable jobs that are already live on a fork.
Edge cases / fork notes
- Defaults to live (
api-m.paypal.com); passenvironment: "sandbox"for sandbox. listTransactionsis one PayPal ≤31-day window; usesearchTransactionsto chunk longer ranges.- Fork before wiring secrets so each account owns its merchant app credentials.
- Keep
LICENSE(MIT),community-icon.svg, and README Intent unchanged unless deliberately updating branding or scope.