Fund

Automate and integrate funding workflows for efficient financial management and transaction processing

Fund is a community skill for implementing funding and payment collection workflows in web applications, covering payment gateway integration, checkout flows, subscription billing, and fund transfer patterns.

What Is This?

Overview

Fund provides patterns for building payment collection and funding mechanisms in applications. It covers payment gateway setup with providers like Stripe, PayPal, and cryptocurrency payment processors, checkout flow implementation with cart management, pricing display, and payment confirmation, subscription billing with recurring charges, plan management, and upgrade or downgrade logic, webhook handling for processing asynchronous payment events and updating order status, and fund transfer patterns for peer-to-peer payments and wallet top-ups. The skill enables developers to build reliable payment infrastructure that handles the complexity of financial transactions.

Who Should Use This

This skill serves developers integrating payment processing into web or mobile applications, teams building marketplace platforms with multi-party payment flows, and engineers implementing subscription billing systems.

Why Use It?

Problems It Solves

Payment integration requires handling multiple failure modes including declined cards, network timeouts, and duplicate charges. Subscription lifecycle management involves trial periods, proration, cancellation, and reactivation logic. Webhook processing must be idempotent to handle duplicate delivery from payment providers. Currency formatting, tax calculation, and regional pricing add complexity to checkout flows.

Core Highlights

Payment intent creation securely initiates transactions on the server side. Checkout session management tracks cart state through the payment process. Webhook handlers process payment events with idempotent operations. Subscription management automates recurring billing and plan changes.

How to Use It?

Basic Usage

import Stripe from 'stripe';

const stripe = new Stripe(
  process.env.STRIPE_SECRET_KEY!);

// Create a payment intent
async function createPayment(
  amount: number,
  currency: string
) {
  const intent =
    await stripe.paymentIntents
      .create({
        amount,
        currency,
        automatic_payment_methods:
          { enabled: true },
      });

  return {
    clientSecret:
      intent.client_secret,
    intentId: intent.id,
  };
}

// Create a checkout session
async function createCheckout(
  items: {
    name: string;
    price: number;
    qty: number;
  }[]
) {
  const session =
    await stripe.checkout.sessions
      .create({
        mode: 'payment',
        line_items: items.map(
          (i) => ({
            price_data: {
              currency: 'usd',
              product_data:
                { name: i.name },
              unit_amount: i.price,
            },
            quantity: i.qty,
          })),
        success_url:
          `${process.env.URL}`
          + '/success',
        cancel_url:
          `${process.env.URL}`
          + '/cancel',
      });

  return { url: session.url };
}

Real-World Examples

import Stripe from 'stripe';

const stripe = new Stripe(
  process.env.STRIPE_SECRET_KEY!);

// Webhook handler
async function handleWebhook(
  body: Buffer,
  signature: string
) {
  const event =
    stripe.webhooks
      .constructEvent(
        body, signature,
        process.env
          .STRIPE_WEBHOOK_SECRET!
      );

  switch (event.type) {
    case 'payment_intent'
        + '.succeeded': {
      const intent = event.data
        .object as
        Stripe.PaymentIntent;
      await db.orders.update({
        where: { paymentId:
          intent.id },
        data: {
          status: 'paid',
          paidAt: new Date(),
        },
      });
      break;
    }
    case 'invoice.paid': {
      const invoice = event.data
        .object as Stripe.Invoice;
      await db.subscriptions
        .update({
          where: { stripeSubId:
            invoice
              .subscription as
              string },
          data: {
            status: 'active',
            currentPeriodEnd:
              new Date(
                invoice
                  .period_end
                  * 1000),
          },
        });
      break;
    }
  }
}

// Subscription creation
async function subscribe(
  customerId: string,
  priceId: string
) {
  const sub =
    await stripe.subscriptions
      .create({
        customer: customerId,
        items: [{ price:
          priceId }],
        payment_behavior:
          'default_incomplete',
        expand:
          ['latest_invoice'
            + '.payment_intent'],
      });
  return sub;
}

Advanced Tips

Use idempotency keys when creating payment intents to prevent duplicate charges from network retries. Store webhook event IDs and skip processing duplicates for reliable event handling. Implement optimistic UI updates on the client while confirming payment status through webhooks on the server.

When to Use It?

Use Cases

Build an e-commerce checkout with Stripe payment intents and real-time order status updates via webhooks. Create a SaaS subscription platform with tiered pricing, trial periods, and automated billing. Implement a marketplace with split payments distributed between sellers and the platform.

Related Topics

Payment processing, Stripe integration, subscription billing, webhook handling, and e-commerce development.

Important Notes

Requirements

A payment provider account such as Stripe with API keys. Server-side runtime for secure payment intent creation. HTTPS endpoint for receiving webhook events.

Usage Recommendations

Do: create payment intents on the server to keep secret keys secure. Verify webhook signatures before processing events. Use test mode API keys during development to avoid real charges.

Don't: expose secret API keys in client-side code. Process payments without webhook confirmation as client-side success callbacks can be unreliable. Skip idempotency handling when retrying failed payment operations.

Limitations

Payment providers charge transaction fees that vary by region and payment method. Webhook delivery is not guaranteed to be exactly once, requiring idempotent handlers. International payments involve currency conversion and compliance requirements that add complexity.