with-xmoney
v0.0.3
Published
A Cloudflare Worker library that adds X Money OAuth authentication and payment capabilities to your application.
Readme
withXMoney - Cloudflare Worker X Money Integration
A Cloudflare Worker library that adds X Money OAuth authentication and payment capabilities to your application.
Quick Start
import { withXMoney, XMoneyClient } from "with-xmoney";
export default {
fetch: withXMoney(
{
client_id: "your-domain.com",
client_username: "your_x_username",
webhook: async (env, username, metadata) => {
console.log(`Payment received for ${username}, metadata: ${metadata}`);
},
},
async (request, env, ctx) => {
if (ctx.user) {
return new Response(
`Hello ${ctx.user.username}! Balance: $${ctx.user.client_balance}`,
);
}
return new Response("Please login");
},
),
};Configuration
Config Object
interface Config {
client_id: string; // Your domain (e.g., 'example.com')
client_username: string; // Your X username
webhook?: (env: Env, username: string, metadata: string) => Promise<void>;
}Authentication Flow
1. Setup OAuth Client
Users can login to your app using X Money accounts:
// Redirect users to login
const loginUrl = `/authorize?client_id=your-domain.com&redirect_uri=https://your-domain.com/callback&state=random-state`;2. Handle OAuth Callback
// In your callback handler
if (url.pathname === "/callback") {
const code = url.searchParams.get("code");
const state = url.searchParams.get("state");
// Exchange code for token
const tokenResponse = await fetch("/token", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
grant_type: "authorization_code",
code,
client_id: "your-domain.com",
}),
});
const { access_token } = await tokenResponse.json();
// Token is automatically set as HTTP-only cookie
}3. Access User Data
async function handler(request, env, ctx) {
if (ctx.user) {
console.log("User:", ctx.user.username);
console.log("Balance:", ctx.user.client_balance);
console.log("Verified:", ctx.user.verified);
}
if (ctx.access_token) {
const client = new XMoneyClient(ctx.access_token);
// Use client for API calls
}
}Payment Operations
Creating Budgets
const client = new XMoneyClient(ctx.access_token);
const budget = await client.createBudget(10.0, 300); // $10 for 5 minutes
console.log("Budget secret:", budget.budget_secret);Charging Payments
// Charge using budget (no auth required)
await client.charge({
budget_secret: "uuid-secret",
amount_usd: 5.0,
payout: {
alice: 0.6, // 60% to alice
bob: 0.4, // 40% to bob
},
detail: "Service payment",
});
// Direct charge (requires auth)
await client.charge({
amount_usd: 10.0,
detail: "Direct payment",
});Getting Budget Info
const budget = await client.getBudget("budget-secret");
console.log("Remaining:", budget.remaining_amount);
console.log("Expires:", budget.expires_at);Transaction History
const transactions = await client.getTransactions(50, 0);
console.log("Recent transactions:", transactions.transactions);Deposits
Generate Deposit URLs
const depositUrl = XMoneyClient.generateDepositUrl(
"alice", // username to receive funds
"your-domain.com", // your client_id
{
message: "Order Payment",
amount_usd: 25.0,
metadata: "order123",
},
);
// Redirect user to depositUrl for paymentHandle Deposit Webhooks
const config = {
client_id: "your-domain.com",
client_username: "your_x_username",
webhook: async (env, username, metadata) => {
console.log(`Payment completed for ${username}`);
console.log(`Metadata: ${metadata}`);
// You can now verify the payment by checking user balance
// or transaction history via the API
},
};Available Context
The handler receives extended context with:
interface Context {
user?: {
x_user_id: string;
username: string;
name: string;
profile_image_url: string;
verified: boolean;
balance: number; // total balance across all clients
client_balance: number; // balance allocated to your client
};
access_token?: string;
}Automatic Endpoints
withXMoney automatically handles these endpoints:
/.well-known/stripeflare.json- Client configuration/stripeflare/{username}/{metadata}- Webhook endpoint/authorize- OAuth authorization/oauth/callback- OAuth callback/token- Token exchange
Error Handling
try {
const client = new XMoneyClient(ctx.access_token);
await client.charge({ amount_usd: 10.0 });
} catch (error) {
console.error("Payment failed:", error.message);
return new Response("Payment failed", { status: 400 });
}Security Notes
- Access tokens are stored in HTTP-only cookies (90 days)
- Authorization header (
Bearer token) is also supported - Redirect URIs must match the client_id domain
- All API calls are made over HTTPS
Client Budgets
- Each user has separate balance pools per client
- Payments only use funds allocated to your client
- 5% platform fee is automatically deducted
- Remaining funds are distributed according to payout percentages
