Svelte SDK

npm version GitHub Svelte SDK for integrating Reevit unified payments with reactive stores.

Installation

npm install @reevit/svelte @reevit/core

Quick Start

The simplest way to integrate Reevit is using the ReevitCheckout component.
<script lang="ts">
  import { ReevitCheckout } from '@reevit/svelte';
  import '@reevit/svelte/styles.css';

  const handleSuccess = (event) => {
    console.log('Payment success!', event.detail);
  };

  const handleError = (event) => {
    console.error('Payment failed:', event.detail);
  };
</script>

<ReevitCheckout
  publicKey="pfk_test_xxx.secret"
  amount={10000}
  currency="GHS"
  email="customer@example.com"
  reference="ORD-12345"
  on:success={handleSuccess}
  on:error={handleError}
>
  <button slot="default" let:handleOpen let:isLoading on:click={handleOpen} disabled={isLoading}>
    {isLoading ? 'Loading...' : 'Pay GHS 100.00'}
  </button>
</ReevitCheckout>

Props Reference

PropTypeRequiredDescription
publicKeystringYour project’s public key
amountnumberAmount in smallest unit
currencystring3-letter currency code
emailstringCustomer’s email
phonestringCustomer’s phone number
referencestringYour transaction reference
metadataobjectOptional key-value pairs for your own tracking
paymentMethodsstring[]Enabled payment methods
themeReevitThemeCustomization options
isOpenbooleanControl modal visibility manually
initialPaymentIntentPaymentIntentPre-created intent for controlled mode
apiBaseUrlstringCustom API URL

Events

EventTypeDescription
on:successCustomEvent<PaymentResult>Fired on successful payment
on:errorCustomEvent<PaymentError>Fired on error
on:closeCustomEvent<void>Fired when widget is closed

Theming

<ReevitCheckout
  theme={{
    primaryColor: '#FF3E00',
    backgroundColor: '#FFFFFF',
    borderRadius: '10px'
  }}
  publicKey="pfk_test_xxx.secret"
  amount={5000}
  currency="GHS"
  on:success={handleSuccess}
>
  <button slot="default" let:handleOpen on:click={handleOpen}>
    Secure Pay
  </button>
</ReevitCheckout>

Controlled Mode

If you prefer to create the payment intent on your backend before opening the checkout, you can use Controlled Mode.
<ReevitCheckout
  publicKey="pfk_test_xxx.secret"
  initialPaymentIntent={myPreCreatedIntent}
  on:success={handleSuccess}
>
  <button slot="default" let:handleOpen on:click={handleOpen}>
    Open Pre-paid Checkout
  </button>
</ReevitCheckout>
In this mode, the SDK skips the initial intent creation step and proceeds directly to payment method selection or provider confirmation.
For full control over the payment flow, use the createReevitStore factory.
<script lang="ts">
  import { createReevitStore } from '@reevit/svelte';

  const store = createReevitStore({
    config: {
      publicKey: 'pfk_test_xxx.secret',
      amount: 5000,
      currency: 'GHS',
      email: 'customer@example.com',
    },
    apiBaseUrl: 'http://localhost:8080',
    onSuccess: (res) => console.log('Payment done!', res),
    onError: (err) => console.error('Payment failed:', err),
  });

  $: state = $store;
</script>

<button on:click={() => store.initialize()}>Start Payment</button>

{#if state.status === 'ready'}
  <div>
    <h3>Select Payment Method</h3>
    <button on:click={() => store.selectMethod('card')}>💳 Card</button>
    <button on:click={() => store.selectMethod('mobile_money')}>📱 Mobile Money</button>
  </div>
{/if}

{#if state.status === 'success'}
  <div>✅ Payment successful!</div>
{/if}

{#if state.error}
  <div class="error">
    {state.error.message}
    <button on:click={() => store.reset()}>Try Again</button>
  </div>
{/if}

PSP Bridge Functions

For advanced use cases, use PSP bridge functions directly.

Stripe

import { createStripeInstance, confirmStripePayment } from '@reevit/svelte';

const stripe = await createStripeInstance('pfk_test_xxx.secret');
const elements = stripe.elements({ clientSecret: 'pi_xxx_secret_xxx' });
const paymentElement = elements.create('payment');
paymentElement.mount('#payment-element');

// Later, confirm payment
await confirmStripePayment({
  publishableKey: 'pfk_test_xxx.secret',
  clientSecret: 'pi_xxx_secret_xxx',
  elements,
  onSuccess: (result) => console.log('Paid:', result.paymentIntentId),
  onError: (err) => console.error(err.message),
});

Monnify (Nigeria)

import { openMonnifyModal } from '@reevit/svelte';

await openMonnifyModal({
  apiKey: 'MK_TEST_xxx',
  contractCode: '1234567890',
  amount: 5000,
  currency: 'NGN',
  reference: 'TXN_12345',
  customerName: 'John Doe',
  customerEmail: 'john@example.com',
  onSuccess: (result) => console.log('Paid:', result.transactionReference),
  onClose: () => console.log('Closed'),
});

M-Pesa (Kenya/Tanzania)

import { initiateMPesaSTKPush } from '@reevit/svelte';

const result = await initiateMPesaSTKPush(
  {
    phoneNumber: '254712345678',
    amount: 500,
    reference: 'TXN_12345',
    onInitiated: () => console.log('STK Push sent'),
    onSuccess: (result) => console.log('Paid:', result.transactionId),
    onError: (err) => console.error(err.message),
  },
  '/api/mpesa/stk-push'
);

SvelteKit Integration

For SvelteKit applications, use the component in +page.svelte:
<script>
  import { ReevitCheckout } from '@reevit/svelte';
  import '@reevit/svelte/styles.css';
  import { browser } from '$app/environment';
</script>

{#if browser}
  <ReevitCheckout
    publicKey="pfk_test_xxx.secret"
    amount={5000}
    currency="GHS"
    on:success={(e) => console.log('Paid!', e.detail)}
  >
    <button slot="default" let:handleOpen on:click={handleOpen}>
      Pay Now
    </button>
  </ReevitCheckout>
{/if}

Supported Providers

ProviderCountriesPayment Methods
PaystackNG, GH, ZA, KECard, Mobile Money, Bank
FlutterwaveNG, GH, KE, ZA+Card, Mobile Money, Bank
HubtelGHMobile Money
StripeGlobal (50+)Card, Apple Pay, Google Pay
MonnifyNGCard, Bank Transfer, USSD
M-PesaKE, TZMobile Money (STK Push)