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

  1. Log and inspect payment.success payload/error code from the gateway response before this throw fires
  2. Retry idempotently for transient gateway failures (timeouts, 5xx) and only fail on definitive declines
  3. 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

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


AI-assisted analysis of sickn33/agentic-awesome-skills@58d857988f (2026-08-26). Data as JSON: /api/errors/a9d8fa7d7faa0962. Report an issue: GitHub.