You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

5.2 KiB

Phase 7: Payment (PayPal Integration)

Status: Todo Progress: 0/12 tasks (0%) Started: - Completed: - Assigned to: -


Overview

Integrate PayPal payment gateway: create order, capture payment, handle webhooks, and manage payment success/failure flows.

Goal: Users can pay for their orders securely via PayPal.


Dependencies

  • Phase 5: Cart (payment requires cart data)
  • Phase 6: Checkout (billing info needed for order)
  • ⚠️ Required: PayPal credentials (CLIENT_ID, CLIENT_SECRET)

Tasks

Setup

  • Install PayPal SDK

    pnpm add @paypal/checkout-server-sdk
    
  • Configure PayPal credentials in .env

    PAYPAL_CLIENT_ID=xxx
    PAYPAL_CLIENT_SECRET=xxx
    PAYPAL_MODE=sandbox  # or 'live' for production
    
  • Add PayPal config to nuxt.config.ts

    runtimeConfig: {
      paypal: {
        clientId: process.env.PAYPAL_CLIENT_ID,
        clientSecret: process.env.PAYPAL_CLIENT_SECRET,
        mode: process.env.PAYPAL_MODE || 'sandbox',
      },
      public: {
        paypalClientId: process.env.PAYPAL_CLIENT_ID, // For client-side SDK
      },
    }
    

API Endpoints

  • Create /api/payment/paypal/create.post.ts endpoint

    • Body: { cartId, billingAddress }
    • Create PayPal order via SDK
    • Amount: cart total in EUR
    • Description: "Makerspace-Jahreskarte"
    • Return: { orderId, approvalUrl }
    • See: PayPal Orders API v2
  • Create /api/payment/paypal/capture.post.ts endpoint

    • Body: { orderId, paypalOrderId }
    • Capture PayPal payment
    • If successful:
      • Create order in local DB (orders, order_items)
      • Queue order for X-API submission (BullMQ)
      • Clear user's cart
      • Return: { success: true, orderNumber }
    • If failed:
      • Return: { success: false, error }
  • Create /api/payment/paypal/webhook.post.ts endpoint

    • Verify webhook signature (PayPal SDK)
    • Handle events:
      • CHECKOUT.ORDER.APPROVED
      • PAYMENT.CAPTURE.COMPLETED
      • PAYMENT.CAPTURE.DENIED
    • Update order status in DB based on event
    • Log all webhook events
    • Return: 200 OK (acknowledge receipt)

Client-Side Integration

  • Integrate PayPal button on checkout
    • File: components/Checkout/PayPalButton.vue
    • Load PayPal JavaScript SDK
    • Render PayPal button
    • On click: Call /api/payment/paypal/create
    • On approve: Call /api/payment/paypal/capture
    • On error: Show error message
    • See: PayPal Checkout Integration guide

Payment Flows

  • Implement payment success flow

    • After successful capture:
      • Redirect to /bestätigung/[orderNumber] (order confirmation page)
      • Show success message + order details
      • Show estimated delivery/activation time
      • Send confirmation email (optional for MVP)
  • Implement payment error handling

    • On capture failure:
      • Show user-friendly error message
      • Keep cart intact (don't clear)
      • Log error for debugging
      • Offer retry or alternative payment method (future)

Testing

  • Test PayPal sandbox

    • Create sandbox account on PayPal Developer Portal
    • Use sandbox credentials in .env
    • Test complete flow: create → approve → capture
    • Test with PayPal test cards
    • Verify order is created in local DB
  • Add payment status tracking

    • Order status field: 'pending', 'paid', 'failed', 'completed'
    • Update status after PayPal capture
    • Display status in user's order history
  • Document PayPal integration

    • Document PayPal API flow
    • Document webhook events and handling
    • Document error scenarios and recovery
    • Document sandbox vs production setup
  • Test webhook handling

    • Use PayPal webhook simulator in sandbox
    • Send test events to webhook endpoint
    • Verify events are processed correctly
    • Verify order status updates

Acceptance Criteria

  • PayPal SDK is installed and configured
  • /api/payment/paypal/create endpoint works
  • /api/payment/paypal/capture endpoint works
  • /api/payment/paypal/webhook endpoint works
  • PayPal button renders on checkout page
  • Can create PayPal order successfully
  • Can capture payment successfully
  • Order is created in DB after successful payment
  • Cart is cleared after successful payment
  • User is redirected to confirmation page
  • Payment errors are handled gracefully
  • Webhook signature verification works
  • Webhook events update order status
  • Payment flow is documented

Notes

  • Sandbox Testing: Use PayPal sandbox for development
  • Webhook URL: Must be publicly accessible (use ngrok for local testing)
  • Currency: EUR for all transactions
  • Amount Precision: PayPal requires 2 decimal places (e.g., "19.99")
  • Order Number: Generate unique order number (e.g., "EXP-2025-0001")

Blockers

  • ⚠️ PayPal Credentials: Need sandbox credentials to test integration
  • ⚠️ Webhook Testing: Need public URL for webhook endpoint (ngrok)