Docs/API Reference

API Reference

Complete reference documentation for the Sunny Payments API. Learn how to authenticate, make requests, and handle responses.

Base URL
/api/v1

Introduction

The Sunny Payments API is organized around REST. Our API accepts JSON-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs.

Key Concepts

  • RESTful Design - Predictable, resource-oriented URLs with standard HTTP methods
  • JSON Responses - All responses are returned in JSON format
  • Authentication - Secure API key authentication for all requests
  • Test Mode - Sandbox environment to test your integration

Authentication

The Sunny API uses API keys to authenticate requests. You can view and manage your API keys in your Dashboard.

API Key Types

Test Keys
sk_test_...

Use in sandbox for testing. No real transactions.

Live Keys
sk_live_...

Use in production for real transactions.

Making Authenticated Requests

Include your API key in the Authorization header:

curl /api/v1/payments \
  -H "Authorization: Bearer sk_test_your_api_key" \
  -H "Content-Type: application/json"

Keep your keys secure! Do not share your secret API keys in publicly accessible areas such as GitHub, client-side code, or public repositories.

Errors

Sunny uses conventional HTTP response codes to indicate the success or failure of an API request.

HTTP Status Codes

200SuccessRequest succeeded
201CreatedResource created successfully
400Bad RequestInvalid parameters provided
401UnauthorizedInvalid or missing API key
404Not FoundResource does not exist
429Too Many RequestsRate limit exceeded
500Server ErrorSomething went wrong on our end

Error Response Format

{
  "error": "Bad Request",
  "message": "Amount, currency, and source are required",
  "timestamp": "2024-12-09T10:30:00Z"
}

Payments

The Payments API allows you to create, retrieve, and manage payments. Payments represent money moving from a customer to your account.

Endpoints

POST
/payments

Create a new payment

GET
/payments

List all payments

GET
/payments/:id

Retrieve a payment

POST
/payments/:id/capture

Capture an authorized payment

POST
/payments/:id/refund

Refund a payment

Create a Payment

Creates a new payment with the specified amount and source.

curl -X POST /api/v1/payments \
  -H "Authorization: Bearer sk_test_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 5000,
    "currency": "KES",
    "source": {
      "type": "card",
      "token": "tok_visa"
    },
    "description": "Order #12345"
  }'

Response

{
  "id": "pay_abc123xyz",
  "status": "succeeded",
  "amount": 5000,
  "currency": "KES",
  "description": "Order #12345",
  "created_at": "2024-12-09T10:30:00Z"
}

Refunds

Refund a payment that has been completed. You can refund the full amount or a partial amount.

POST
/payments/:id/refund

Create a refund

Create a Refund

curl -X POST /api/v1/payments/pay_abc123xyz/refund \
  -H "Authorization: Bearer sk_test_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 2500,
    "reason": "Customer requested refund"
  }'

Customers

Customer objects allow you to store payment sources and track payments for your users.

POST
/customers

Create a customer

GET
/customers/:id

Retrieve a customer

GET
/customers

List all customers

Webhook Events

Webhooks allow you to receive real-time notifications when events happen in your account.

Available Events

payment.succeeded
payment.failed
payment.refunded
subscription.created
subscription.cancelled
payout.completed

Event Payload

{
  "id": "evt_1234567890",
  "type": "payment.succeeded",
  "created_at": "2024-12-09T10:30:00Z",
  "data": {
    "payment": {
      "id": "pay_abc123",
      "amount": 5000,
      "currency": "KES",
      "status": "succeeded"
    }
  }
}

Verifying Signatures

Always verify that webhook requests came from Sunny by checking the signature header.

Each webhook request includes a sunny-signature header. Use your webhook secret to verify this signature before processing the event.

// Verify webhook signature
const signature = request.headers['sunny-signature'];
const payload = request.body;
const secret = process.env.WEBHOOK_SECRET;

// Use HMAC SHA256 to verify
const crypto = require('crypto');
const expected = crypto
  .createHmac('sha256', secret)
  .update(JSON.stringify(payload))
  .digest('hex');

if (signature === expected) {
  // Signature is valid, process the event
  console.log('Webhook verified:', payload.type);
} else {
  // Invalid signature, reject the request
  return res.status(401).send('Invalid signature');
}