npm package: @rockwallet/stripe-sdk
Description: MNEE Pay SDK — Stablecoin custom payment method for Stripe Elements
Latest version: 1.0.0

# Stripe QR Payment SDK

A lightweight SDK that allows merchants to integrate **custom payments via stablecoins** directly into their Stripe checkout flow.

Currently supports **USDC on the Base chain**.

---

## Features

- 💳 Custom payment method inside Stripe Payment Element
- 🔗 Stablecoin payments (USDC)
- 🌐 Works with existing Stripe checkout flows

---

# Installation

Install the SDK:

```bash
npm install @rockwallet/stripe-sdk
```

Import the SDK components:

```ts
import { MneePaymentModal, useMneePayment } from '@rockwallet/stripe-sdk'
```

---

# Integration Guide

## 1. Add Custom Payment Method to Stripe

Add a custom payment method inside the **Stripe Payment Element options**.

```ts
customPaymentMethods: [
  {
    id: 'your_cpmt_id',
    options: {
      type: 'static' as const,
      subtitle: 'Pay with Stablecoins',
    },
  },
]
```

---

# 2. Initialize the Mnee Payment Hook

Add the hook inside your payment form.

```ts
const mnee = useMneePayment({
  integrationId: INTEGRATION_ID,
  onSuccess: ({ transactionHash, amount }) => {
    window.location.href = `${SUCCESS_URL}?tx=${transactionHash}&amount=${amount}`
  },
})
```

### Parameters

| Property          | Description                                 |
| ----------------- | ------------------------------------------- |
| `integrationId` | Stripe Integration id provided by mnee pay  |
| `onSuccess`     | Callback triggered after successful payment |

---

# 3. Update the Submit Handler

Intercept the payment flow when the **custom payment method** is selected.

```ts
if (selectedPaymentMethod === CPMT_ID) {
  mnee.openPayment({
    amount: total,  // product amount in cents
    items: items,   // product details
    shippingInfo: shippingInfo  // customer shipping info
  })

  return // modal handles payment flow
}
```

---

# 4. Add the Payment Modal

Add the modal component at the **end of your payment form**.

```tsx
<MneePaymentModal
  isOpen={mnee.isOpen}
  onClose={mnee.closePayment}
  amount={mnee.amount}
  items={mnee.items}
  shippingInfo={mnee.shippingInfo}
  integrationId={INTEGRATION_ID}
  onSuccess={mnee.handleSuccess}
/>
```

---

# 5. Webhook Integration

Merchants need to set up a **webhook** to record payments in Stripe after the user completes payment. The webhook also reports the Stripe payment record ID back to Mnee Pay.

Example Webhook (Next.js)

```ts
import { NextRequest, NextResponse } from 'next/server'
import Stripe from 'stripe'
import crypto from 'crypto'

const stripeKey = "your_stripe_secret_key"
const mneePayApiKey = "your_mnee_pay_api_key (provided by mnee pay)"
const cpm_id = "Your_cpmd_id"
const mneeBaseUrl = "mnee_pay backend url"

const stripe = new Stripe(stripeKey!, { apiVersion: '2026-01-28.clover' })

export async function POST(request: NextRequest) {
  try {
    const rawBody = await request.text()
    const signature = request.headers.get('X-Webhook-Signature')

    if (!signature) return NextResponse.json({ error: 'Missing signature' }, { status: 401 })

    const expectedSignature = crypto.createHmac('sha256', mneePayApiKey!)
      .update(rawBody)
      .digest('hex')

    if (signature !== expectedSignature) {
      return NextResponse.json({ error: 'Invalid signature' }, { status: 401 })
    }

    const payload = JSON.parse(rawBody)

    // Only handle successful payments
    if (payload.event !== 'SUCCESS') return NextResponse.json({ received: true })

    const { transactionId, stripeUserMetadata, payment, rwId, referenceId, order } = payload

    // Find or create customer
    const existingCustomers = await stripe.customers.search({ query: `email:'${stripeUserMetadata?.email}'` })
    const customer = existingCustomers.data[0] ?? await stripe.customers.create({
      name: `${stripeUserMetadata?.firstName ?? ''} ${stripeUserMetadata?.lastName ?? ''}`.trim(),
      email: stripeUserMetadata?.email,
      address: { country: stripeUserMetadata?.address?.country },
    })

    // Create or attach custom payment method
    const existingPaymentMethods = await stripe.paymentMethods.list({ customer: customer.id, type: 'custom' })
    const paymentMethod = existingPaymentMethods.data[0] ?? await stripe.paymentMethods.create({
      type: 'custom',
      custom: { type: cpm_id! },
    }).then(pm => stripe.paymentMethods.attach(pm.id, { customer: customer.id }).then(() => pm))

    // Record payment in Stripe
    const paymentRecord = await stripe.paymentRecords.reportPayment({
      amount_requested: { value: payment.amountUsdCents, currency: 'usd' },
      payment_method_details: { payment_method: paymentMethod.id },
      processor_details: { type: 'custom', custom: { payment_reference: payment.paymentTxHash } },
      metadata: { rwId, referenceId, mneeTxId: payment.mneeTxId },
      initiated_at: Math.floor(Date.now() / 1000),
      outcome: 'guaranteed',
      guaranteed: { guaranteed_at: Math.floor(Date.now() / 1000) },
      customer_details: { customer: customer.id },
      description: `MNEE Payment ${payment.paymentTxHash}`,
    }, { idempotencyKey: `mnee_${transactionId}` })

    // Report back to Mnee Pay
    await fetch(`${mneeBaseUrl}/integrations/server/stripe/payment-record`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', 'x-api-key': mneePayApiKey! },
      body: JSON.stringify({ transactionId, stripePaymentRecordId: paymentRecord.id }),
    })

    return NextResponse.json({ success: true })
  } catch (error: any) {
    return NextResponse.json({ error: error.message }, { status: 500 })
  }
}
```

# Types

The SDK expects the following TypeScript types for **items and shipping information**.

## Items

```ts
export interface Items {
  product: {
    id: string
    name: string
    price: number // in cents
  }
  quantity: number
}
```

## ShippingInfo

```ts
export interface ShippingInfo {
  firstName?: string
  lastName?: string
  email?: string
  address?: string
  city?: string
  state?: string
  country?: string
  zipCode?: string
}
```

---

# Payment Flow

1. User selects **Pay with Stablecoins**
2. SDK opens the **QR payment modal**
3. User scans QR with wallet
4. User pays using **USDC on Base**
5. Transaction is verified
6. `onSuccess` callback is triggered
7. Stripe payment record is created via webhook
8. Stripe payment record ID is sent back to Mnee Pay
9. User is redirected to success page

---

# Environment Variables

```env
CPMT_ID=your_custom_payment_method_id
INTEGRATION_ID=your_stripe_integration_id
```

---

# Requirements

- React
- Stripe Payment Element
- Node.js 18+

---

# Supported Networks

| Network | Token |
| ------- | ----- |
| Base    | USDC  |

More networks coming soon.

---

# License

MIT