sickn33/agentic-awesome-skills · error · Error
Payment failed
Error message
Payment failed
What it means
Thrown in the fp-pragmatic 'Before' example when processPayment returns a result object with success falsy — the payment gateway or charge step declined the order. The skill replaces this control flow with a TaskEither chain where payment failure becomes a left value.
Source
Thrown at skills/fp-pragmatic/SKILL.md:509
: E.left('Valid age required')
),
E.map(({ email, age }) => ({ email, age }))
)
```
### Promise Chain to TaskEither
```typescript
// Before
async function processOrder(orderId: string): Promise<Receipt> {
const order = await fetchOrder(orderId)
if (!order) throw new Error('Order not found')
const validated = await validateOrder(order)
if (!validated.success) throw new Error(validated.error)
const payment = await processPayment(validated.order)
if (!payment.success) throw new Error('Payment failed')
return generateReceipt(payment)
}
// After
const processOrder = (orderId: string): TE.TaskEither<string, Receipt> =>
pipe(
fetchOrderTE(orderId),
TE.flatMap(order =>
order ? TE.right(order) : TE.left('Order not found')
),
TE.flatMap(validateOrderTE),
TE.flatMap(processPaymentTE),
TE.map(generateReceipt)
)
```
---View on GitHub (pinned to 58d857988f)
Solutions
- Log and inspect payment.success payload/error code from the gateway response before this throw fires
- Retry idempotently for transient gateway failures (timeouts, 5xx) and only fail on definitive declines
- Model the step as TaskEither and use TE.filterOrElse on the payment result so failure flows as data
Example fix
// before
const payment = await processPayment(validated.order)
if (!payment.success) throw new Error('Payment failed')
// after
const pay = (o: Order) =>
TE.filterOrElse(
TE.tryCatch(() => processPayment(o), E.toError),
(p) => p.success,
() => new Error('Payment failed')
) Defensive patterns
Strategy: retry
Try / catch
try {
await processOrder(orderId)
} catch (e) {
if (e instanceof Error && e.message === 'Payment failed') {
// inspect gateway reason; retry only transient causes idempotently
}
throw e
} Prevention
- Make payment calls idempotent with idempotency keys before enabling retries
- Classify gateway error codes into transient vs definitive declines
When it happens
Trigger: Calling processOrder where validateOrder succeeds but processPayment resolves to { success: false, ... } — insufficient funds, gateway timeout mapped to failure, or a declined test card.
Common situations: Sandbox payment gateways returning declines for specific test card numbers; expired customer payment tokens; amount/currency mismatches between your validation and the gateway.
Related errors
- Order not found
- HTTP ${response.status}
- HTTP ${response.status}: ${response.statusText}
- Order not found
- Out of stock
AI-assisted analysis of sickn33/agentic-awesome-skills@58d857988f (2026-08-26).
Data as JSON: /api/errors/a9d8fa7d7faa0962.
Report an issue: GitHub.