@moneygraph/sdk
Version:
AI-native SDK for global payouts powered by StratosPay
141 lines (140 loc) • 5.11 kB
JavaScript
;
/**
* MoneyGraph SDK - Payouts Module
*
* Global payouts with automatic KYC verification.
* Requires a confirmed quote before sending.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.PayoutsModule = void 0;
const client_1 = require("../api/client");
// Sandbox payout storage
const sandboxPayouts = new Map();
function generatePayoutId() {
return `payout_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
}
class PayoutsModule {
constructor(client, onboard) {
this.client = client;
this.onboard = onboard;
}
/**
* Send a payout
* Requires KYC approval and a confirmed quote
*/
async send(params) {
// CRITICAL: Check KYC status before allowing payout
const kycCheck = await this.onboard.canPayout(params.customer_id);
if (!kycCheck.allowed) {
const errorCode = kycCheck.status === 'PENDING' ? 'KYC_PENDING' : 'KYC_REJECTED';
throw new client_1.MoneyGraphError(kycCheck.reason || 'KYC not approved', errorCode, 403);
}
if (this.client.isSandbox) {
const payout = {
id: generatePayoutId(),
quote_id: params.quote_id,
customer_id: params.customer_id,
amount: 0, // Would be set from quote
currency: 'USD', // Would be set from quote
recipient: params.recipient,
status: 'pending',
reference: params.reference || `ref_${Date.now()}`,
narration: params.narration,
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
};
sandboxPayouts.set(payout.id, payout);
// Simulate status progression
this.simulatePayoutProgress(payout.id);
return payout;
}
return this.client.post('/payouts/send', params);
}
/**
* Get payout status
*/
async getStatus(payoutId) {
if (this.client.isSandbox) {
const payout = sandboxPayouts.get(payoutId);
if (!payout) {
throw new client_1.MoneyGraphError('Payout not found', 'NOT_FOUND', 404);
}
return payout;
}
return this.client.get(`/payouts/${payoutId}`);
}
/**
* List payouts for a customer
*/
async list(customerId, options = {}) {
if (this.client.isSandbox) {
const payouts = Array.from(sandboxPayouts.values())
.filter(p => p.customer_id === customerId)
.filter(p => !options.status || p.status === options.status);
return {
data: payouts,
links: { first: '?page=1', last: '?page=1', prev: null, next: null },
meta: {
current_page: 1,
from: 1,
last_page: 1,
path: '/payouts',
per_page: 20,
to: payouts.length,
total: payouts.length,
links: [],
},
};
}
return this.client.get('/payouts', {
customer_id: customerId,
page: options.page || 1,
...(options.status && { status: options.status }),
});
}
/**
* Cancel a pending payout
*/
async cancel(payoutId) {
if (this.client.isSandbox) {
const payout = sandboxPayouts.get(payoutId);
if (!payout) {
throw new client_1.MoneyGraphError('Payout not found', 'NOT_FOUND', 404);
}
if (payout.status !== 'pending') {
throw new client_1.MoneyGraphError('Only pending payouts can be cancelled', 'VALIDATION_ERROR', 400);
}
payout.status = 'cancelled';
payout.updated_at = new Date().toISOString();
sandboxPayouts.set(payoutId, payout);
return payout;
}
return this.client.post(`/payouts/${payoutId}/cancel`);
}
/**
* Simulate payout status progression (sandbox only)
*/
simulatePayoutProgress(payoutId) {
if (!this.client.isSandbox)
return;
// pending -> processing (after 10 seconds)
setTimeout(() => {
const payout = sandboxPayouts.get(payoutId);
if (payout && payout.status === 'pending') {
payout.status = 'processing';
payout.updated_at = new Date().toISOString();
sandboxPayouts.set(payoutId, payout);
}
}, 10000);
// processing -> completed (after 30 seconds)
setTimeout(() => {
const payout = sandboxPayouts.get(payoutId);
if (payout && payout.status === 'processing') {
payout.status = 'completed';
payout.updated_at = new Date().toISOString();
sandboxPayouts.set(payoutId, payout);
}
}, 30000);
}
}
exports.PayoutsModule = PayoutsModule;