/

Migrating from Stripe

Wyrr's API design is intentionally familiar to Stripe users. Most concepts map directly. This guide shows side-by-side comparisons to help you migrate quickly.

Stripe ConceptWyrr EquivalentNotes
Secret KeyAPI Key + API SecretWyrr uses key pair for enhanced security
PaymentIntentCollectionSame lifecycle: create, confirm, capture
CustomerCustomerNearly identical API
PayoutPayoutWyrr adds mobile wallet + stablecoin destinations
Webhook EndpointWebhook EndpointHMAC-SHA256 vs Stripe signature scheme
Product / PriceProduct / PriceSame model
DisputeDisputeSame model
BalanceBalanceMulti-currency with FX built in
Stripe.jsWyrr.jsSame pattern: client-side confirmation
DashboardDashboardFull-featured merchant portal

Authentication

Stripe uses a single secret key. Wyrr uses a key pair (public + secret) and short-lived access tokens for enhanced security.

Stripe
1const stripe = require('stripe')('sk_live_...');
2
3// Stripe uses the secret key directly on every request
4const customer = await stripe.customers.create({
5  email: 'test@example.com'
6});
Wyrr
1const Wyrr = require('@wyrr/node');
2
3// Wyrr uses a key pair and auto-manages token lifecycle
4const client = new Wyrr({
5  apiKey: 'wyrr_live_pk_...',
6  apiSecret: 'wyrr_live_sk_...'
7});
8
9const customer = await client.customers.create({
10  email: 'test@example.com'
11});

Customers

Customer creation is nearly identical. Wyrr adds phone as a first-class field and uses a different ID prefix.

Stripe
1const customer = await stripe.customers.create({
2  email: 'customer@example.com',
3  name: 'Amina Bello',
4  metadata: {
5    segment: 'enterprise'
6  }
7});
8
9console.log(customer.id); // cus_abc123...
Wyrr
1const customer = await client.customers.create({
2  email: 'customer@example.com',
3  name: 'Amina Bello',
4  phone: '+2348012345678', // First-class phone support
5  metadata: {
6    segment: 'enterprise'
7  }
8});
9
10console.log(customer.id); // cus_8a3b7c9d

Payment Intents vs Collections

Stripe's PaymentIntent maps directly to Wyrr's Collection. The core flow is the same: create server-side, confirm client-side. Wyrr uses the term "collection" to represent the full payment lifecycle.

Stripe (PaymentIntent)
1// Server-side: create PaymentIntent
2const paymentIntent = await stripe.paymentIntents.create({
3  amount: 5000,
4  currency: 'usd',
5  customer: 'cus_abc123',
6  payment_method_types: ['card'],
7  metadata: {
8    order_id: '12345'
9  }
10});
11
12// Send client_secret to frontend
13res.json({
14  clientSecret: paymentIntent.client_secret
15});
16
17// Client-side: confirm with Stripe.js
18const { error } = await stripe.confirmCardPayment(
19  clientSecret,
20  { payment_method: { card: cardElement } }
21);
Wyrr (Collection)
1// Server-side: create Collection
2const collection = await client.collections.create({
3  amount: 5000,
4  currency: 'USD',
5  customerId: 'cus_8a3b7c9d',
6  paymentMethod: 'card',
7  metadata: {
8    orderId: '12345'
9  }
10}, { idempotencyKey: 'order-12345' });
11
12// Send client_secret to frontend
13res.json({
14  clientSecret: collection.client_secret
15});
16
17// Client-side: confirm with Wyrr.js
18const { error } = await wyrr.confirmPayment(
19  clientSecret,
20  { paymentMethod: { card: cardElement } }
21);

Payouts

Stripe payouts go to connected accounts or external accounts. Wyrr payouts support bank accounts, mobile wallets, and stablecoins with built-in FX.

Stripe
1// Payout to a connected account's bank
2const payout = await stripe.payouts.create({
3  amount: 25000,
4  currency: 'usd',
5  method: 'standard'
6}, {
7  stripeAccount: 'acct_abc123'
8});
Wyrr
1// Payout to any bank globally (with auto FX)
2const payout = await client.payouts.create({
3  amount: 250000,
4  currency: 'NGN',
5  destination: {
6    type: 'bank_account',
7    bankCode: '044',
8    accountNumber: '0123456789',
9    accountName: 'Adebayo Ogunlesi'
10  },
11  description: 'Vendor payment'
12}, { idempotencyKey: 'payout-may-001' });
13
14// Also supports mobile wallets and stablecoins:
15// destination.type = 'mobile_wallet'
16// destination.type = 'stablecoin'

Webhooks

Both platforms use similar webhook patterns. Key differences: Wyrr uses HMAC-SHA256 (vs Stripe's custom signature scheme), and event type naming uses dots instead of underscores in the resource part.

Stripe
1// Webhook verification
2const event = stripe.webhooks.constructEvent(
3  req.body,
4  req.headers['stripe-signature'],
5  endpointSecret
6);
7
8switch (event.type) {
9  case 'payment_intent.succeeded':
10    const paymentIntent = event.data.object;
11    // Handle success
12    break;
13  case 'payment_intent.payment_failed':
14    // Handle failure
15    break;
16}
Wyrr
1// Webhook verification
2const isValid = wyrr.webhooks.verifySignature(
3  req.body,
4  req.headers['wyrr-signature'],
5  endpointSecret
6);
7
8if (!isValid) return res.status(401).send();
9
10const event = req.body;
11switch (event.type) {
12  case 'payment.succeeded':
13    const collection = event.data;
14    // Handle success
15    break;
16  case 'payment.failed':
17    // Handle failure
18    break;
19}

Ready to migrate?

Our migration team can help you move from Stripe to Wyrr with zero downtime. Typical migration takes 1-2 weeks.

Contact Migration Team