@moneygraph/sdk
Version:
AI-native SDK for global payouts powered by StratosPay
220 lines (178 loc) • 6.79 kB
Markdown
# MoneyGraph SDK Knowledge Base
You are helping build an application that uses the MoneyGraph SDK for global payouts. This document contains everything you need to know.
## Installation
```bash
npm install @moneygraph/sdk
```
## Initialization
```typescript
import { MoneyGraph } from '@moneygraph/sdk';
// API key prefix determines mode:
// sk_test_* = sandbox (mock data, safe for development)
// sk_live_* = live (real transactions!)
const mg = new MoneyGraph({ apiKey: process.env.MONEYGRAPH_API_KEY! });
```
## Critical Rules (MUST FOLLOW)
1. **KYC is REQUIRED before payouts** - The SDK will throw `KYC_PENDING` or `KYC_REJECTED` errors if customer isn't approved
2. **Quote & Confirm pattern** - ALWAYS get quote → confirm quote → send payout
3. **Quotes expire in 2 minutes** - Must confirm and send before expiration
4. **Date format is DD-MM-YYYY** - For birthday and registration dates
5. **Use mock personas in sandbox** - `createMockPersona()` for instant verified customers
## SDK Namespace Reference
| Namespace | Methods |
|-----------|---------|
| `mg.onboard` | createCustomer, getCustomer, updateCustomer, submitKyc, uploadDocument, canPayout, createMockPersona, listDirectors, createDirector, getWallets, listTransactions |
| `mg.payments` | chargeCard, verifyPayment, generateWidgetConfig, generatePopupConfig, generateReference |
| `mg.liquidity` | getQuote, confirmQuote, isQuoteValid, getQuoteTimeRemaining, getRates |
| `mg.payouts` | send, getStatus, list, cancel |
| `mg.reference` | getCountries, getCurrencies, getSourceOfFunds, getMccCodes, getBusinessRegistrationTypes |
## Complete Payout Example
```typescript
import { MoneyGraph, MoneyGraphError } from '@moneygraph/sdk';
const mg = new MoneyGraph({ apiKey: process.env.MONEYGRAPH_API_KEY! });
// Option 1: Use convenience method (recommended)
try {
const payout = await mg.sendPayout({
customerId: 'customer_123',
from: 'USD',
to: 'NGN',
amount: 100,
recipient: {
name: 'Jane Doe',
bank_code: '058',
account_number: '0123456789',
},
});
console.log('Payout sent:', payout.id);
} catch (error) {
if (error instanceof MoneyGraphError) {
if (error.code === 'KYC_PENDING') {
console.log('Customer needs to complete KYC');
} else if (error.code === 'KYC_REJECTED') {
console.log('Customer KYC was rejected');
}
}
}
// Option 2: Manual flow (for custom UI)
const quote = await mg.liquidity.getQuote({ from: 'USD', to: 'NGN', amount: 100 });
// Show quote to user: "You send $100, they receive ₦${quote.to_amount}"
// User confirms...
await mg.liquidity.confirmQuote(quote.id);
const payout = await mg.payouts.send({
quote_id: quote.id,
customer_id: 'customer_123',
recipient: { name: 'Jane', bank_code: '058', account_number: '0123456789' },
});
```
## Customer Types
### Personal Customer
```typescript
const customer = await mg.onboard.createCustomer({
account_type: 'personal',
first_name: 'John',
last_name: 'Doe',
email: 'john@example.com',
phone: '2025551234',
phone_iso2: 'US',
country: 'US',
});
```
### Business Customer
```typescript
const business = await mg.onboard.createCustomer({
account_type: 'business',
first_name: 'Jane',
last_name: 'Smith',
email: 'jane@company.com',
phone: '2025555678',
phone_iso2: 'US',
country: 'US',
business_details: {
business_name: 'Acme Corp',
address: { country: 'US', state: 'CA', city: 'San Francisco', street: '123 Main', postal_code: '94105' },
},
});
```
## KYC Flow
```typescript
// 1. Update with KYC info
await mg.onboard.updateCustomer(customerId, {
birthday: '15-06-1990',
gender: 'male',
id_type: 'PASSPORT',
id_number: 'P123456789',
source_of_fund_id: '22bc46b1-6a5a-493b-96cd-61b986ab698d',
state: 'CA',
city: 'San Francisco',
street: '123 Main Street',
postal_code: '94105',
});
// 2. Upload documents
await mg.onboard.uploadDocument(customerId, 'document', documentFile, 'passport.jpg');
await mg.onboard.uploadDocument(customerId, 'selfie', selfieFile, 'selfie.jpg');
// 3. Submit for review
await mg.onboard.submitKyc(customerId);
// 4. Check status
const { allowed, status } = await mg.onboard.canPayout(customerId);
```
## Mock Personas (Sandbox Only)
```typescript
// Instant verified customers for testing
const verified = await mg.onboard.createMockPersona('business_verified');
const individual = await mg.onboard.createMockPersona('individual_verified');
const pending = await mg.onboard.createMockPersona('pending_kyc');
const rejected = await mg.onboard.createMockPersona('rejected_kyc');
```
## Error Codes
| Code | Meaning |
|------|---------|
| `KYC_PENDING` | Customer KYC is pending review |
| `KYC_REJECTED` | Customer KYC was rejected |
| `KYC_ALREADY_APPROVED` | Cannot modify approved KYC |
| `QUOTE_EXPIRED` | FX quote expired (get new one) |
| `CUSTOMER_NOT_FOUND` | Invalid customer ID |
| `VALIDATION_ERROR` | Invalid request params |
| `RATE_LIMITED` | Too many requests |
## Currency Support
**Pay-In (21):** USD, EUR, NGN, KES, UGX, RWF, TZS, GHS, MWK, XOF, XAF + crypto (USDC, USDT, ETH, BTC)
**Payout (107+ countries):** USD, EUR, GBP, NGN, KES, ZAR, GHS, CNY, JPY, INR, PHP, MXN, BRL, CAD, AUD, and 90+ more
## ⚠️ CORS Warning
This SDK makes direct API calls. For browser apps, use a backend proxy (Supabase Edge Function, Next.js API route, etc.) to avoid CORS issues.
## Accept Payments (Merchants)
Initialize with public key for client-side payments:
```typescript
const mg = new MoneyGraph({
apiKey: 'sk_test_xxx', // Server-side
publicKey: 'pk_test_xxx', // Client-side payments
});
```
### Widget/Popup (Client-side)
```html
<script src="https://stratospay.com/popup.js"></script>
<button onclick="checkout.init({
public_key: 'pk_test_xxx',
external_reference: 'order_' + Date.now(),
amount: 10000,
currency: 'USD',
title: 'Order Payment',
description: 'Order #12345',
customer: { first_name: 'John', last_name: 'Doe', email: 'john@example.com', ip_address: '127.0.0.1' },
billing_address: { country: 'US', city: 'LA', address: '123 Main St', postal_code: '90001' },
onsuccess: (data) => console.log('Success!', data),
onerror: (data) => console.log('Error', data)
})">Pay Now</button>
```
### Test Cards
| Card | Result |
|------|--------|
| `4917484589897107` | Success |
| `5555555555554444` | Success |
| `6011000991300009` | Blocked |
| `4263982640269299` | Requires 3DS |
## Quick Checklist
- [ ] API key set in environment variables
- [ ] Customer created with `createCustomer()`
- [ ] KYC completed and approved (or use `createMockPersona()` in sandbox)
- [ ] Quote obtained with `getQuote()`
- [ ] Quote confirmed with `confirmQuote()`
- [ ] Payout sent with `send()` or `sendPayout()`