Bill your first B2C customer

By the end of this tutorial a customer will have an active subscription and a finalized, paid first invoice. Solvimon will automatically generate and charge subsequent invoices each billing period.

The full flow looks like this:

  1. Tokenize the card in Adyen to get a stored payment method ID
  2. Create the customer in Solvimon, linked to that Adyen shopper
  3. Initialize the subscription, recording the first payment so the first invoice is immediately finalized and paid
  4. Set up webhooks to handle future invoices and payment events

What you’ll need:

  • A Solvimon sandbox API key — see Send your first API request
  • A pricing plan already created in your sandbox — set one up in Desk first
  • A billing entity configured under Settings → Billing entities
  • An Adyen test account with a merchant account configured for recurring payments

Step 1: Tokenize the card in Adyen

Before creating the subscription, tokenize the customer’s card details in Adyen. This stores the card and gives you a recurring_detail_reference you’ll pass to Solvimon later.

1a. Submit the card payment to create the token

$curl -X POST https://checkout-test.adyen.com/v71/payments \
> -H "X-API-KEY: <adyenApiKey>" \
> -H "Content-Type: application/json" \
> -d '{
> "amount": {
> "currency": "EUR",
> "value": 0
> },
> "paymentMethod": {
> "type": "scheme",
> "encryptedCardNumber": "test_4111111111111111",
> "encryptedExpiryMonth": "test_03",
> "encryptedExpiryYear": "test_2030",
> "encryptedSecurityCode": "test_737"
> },
> "merchantAccount": "Adyen_B2C_Subscriptions",
> "recurringProcessingModel": "Subscription",
> "reference": "card_cust_1",
> "shopperReference": "cust_1",
> "storePaymentMethod": true
> }'
  • shopperReference: Your identifier for this customer in Adyen. You’ll use this same value as the Solvimon custom_fields reference in Step 2.
  • storePaymentMethod: true: Tells Adyen to store the card for future recurring charges.
  • recurringProcessingModel: "Subscription": Required for subscription-type recurring payments.

1b. Retrieve the stored payment method ID

$curl -X POST https://checkout-test.adyen.com/v71/paymentMethods \
> -H "X-API-KEY: <adyenApiKey>" \
> -H "Content-Type: application/json" \
> -d '{
> "merchantAccount": "Adyen_B2C_Subscriptions",
> "shopperReference": "cust_1"
> }'

Response:

1{
2 "storedPaymentMethods": [
3 {
4 "id": "WC43X3RL9ZD3LTT5",
5 "lastFour": "1111",
6 "name": "VISA"
7 }
8 ]
9}

Note the id — this is the recurring_detail_reference you’ll use in Step 3.


Step 2: Create the customer

Create the customer in Solvimon and link them to the Adyen shopper via custom_fields. Solvimon uses this to know which PSP payment methods belong to this customer.

$curl -X POST https://test.api.solvimon.com/v1/customers \
> -H "X-API-KEY: <apiKey>" \
> -H "Content-Type: application/json" \
> -d '{
> "reference": "cust_1",
> "type": "INDIVIDUAL",
> "email": "john.doe@gmail.com",
> "roles": ["DEFAULT"],
> "individual": {
> "name": {
> "first_name": "John",
> "last_name": "Doe"
> },
> "residential_address": {
> "country": "NL"
> }
> },
> "custom_fields": [
> {
> "reference": "PAYMENT_GATEWAY:ADYEN:SHOPPER_REFERENCE",
> "value": "cust_1"
> }
> ]
> }'

Parameter notes:

  • reference: Your identifier for this customer. Used to reference them in subsequent API calls.
  • custom_fields.reference: The key identifying which PSP this links to.
    • PAYMENT_GATEWAY:ADYEN:SHOPPER_REFERENCE — for Adyen
    • PAYMENT_GATEWAY:STRIPE:CUSTOMER_ID — for Stripe (use the Stripe cus_... ID as the value)
  • custom_fields.value: The customer’s identifier in the PSP system — must match the shopperReference used in Step 1.

📘 You can only use payment methods that were created under the shopperReference set in custom_fields. Solvimon will reject payment attempts using methods belonging to a different shopper.

📘 See the Customers API reference for all available fields.


Step 3: Initialize the subscription

/init creates the subscription and its first schedule in a single call. Providing first_payment tells Solvimon that the customer already paid (e.g. as part of checkout), which automatically finalizes the first invoice as paid. The payment_method stores the card so Solvimon can auto-charge future invoices.

$curl -X POST https://test.api.solvimon.com/v1/pricing-plan-subscriptions/init \
> -H "X-API-KEY: <apiKey>" \
> -H "Content-Type: application/json" \
> -d '{
> "pricing_plan_subscription": {
> "reference": "cust_1_monthly_eur_20240915",
> "customer_reference": "cust_1",
> "billing_entity_reference": "entity_nl",
> "billing_time": "EXACT",
> "billing_currency": "EUR"
> },
> "pricing_plan_schedules": [
> {
> "pricing_plan_version_selector": {
> "pricing_plan_reference": "monthly_eur"
> },
> "start_at": "2024-09-15T00:00:00Z",
> "end_at": "2025-09-15T00:00:00Z"
> }
> ],
> "first_payment": {
> "payment_acceptor_reference": "adyen_b2c_subscriptions",
> "external_reference": "N9KKLBTLMJS8F6V5",
> "amount": {
> "quantity": "9.99",
> "currency": "EUR"
> },
> "result": "AUTHORIZED"
> },
> "payment_method": {
> "type": "CARD",
> "card": {
> "brand": "VISA",
> "last_four_digits": "1111"
> },
> "integration_reference": "adyen",
> "integration_details": {
> "payment_gateway_variant": "ADYEN",
> "adyen": {
> "recurring_detail_reference": "WC43X3RL9ZD3LTT5"
> }
> }
> }
> }'

Parameter notes:

pricing_plan_subscription:

  • reference: Your identifier for this subscription.
  • customer_reference: The reference of the customer created in Step 2.
  • billing_entity_reference: The billing entity this subscription is invoiced from.
  • billing_time: "EXACT": Billing occurs on the same day of the month as start_at — e.g. if the subscription starts on the 15th, every subsequent invoice is on the 15th. Recommended for B2C.
  • billing_currency: The currency used for all invoices on this subscription.

pricing_plan_schedules:

  • pricing_plan_version_selector.pricing_plan_reference: The pricing plan to use. By default the latest ACTIVE version is used.
  • start_at: Set to the date the customer paid and activated the subscription.
  • end_at: Optional. When set, the subscription ends and no further invoices are generated after this date.

first_payment:

  • Use this when the first payment was collected outside of Solvimon (e.g. during your checkout flow). Providing it causes Solvimon to automatically finalize the first invoice as paid.
  • external_reference: The transaction reference from your PSP for this payment.
  • result: "AUTHORIZED": Confirms the payment succeeded.

payment_method:

  • integration_reference: The reference to the payment provider integration configured in Solvimon.
  • integration_details.adyen.recurring_detail_reference: The stored payment method ID from Step 1b. Solvimon uses this to charge the customer’s card for future invoices.

👍 Default billing terms: Instead of specifying billing_time, billing_currency, and billing_period on every subscription, you can configure defaults under Settings → Default platform settings. They apply automatically when those fields are omitted.

👍 Skipping payment collection? Omit first_payment and payment_method. The subscription and schedule are still created and invoices will be generated — just not auto-charged.


Alternative: Create customer and subscription in one call

If you want to create or update the customer at the same time as initializing the subscription, pass a customer object directly in the init request instead of a customer_reference:

$curl -X POST https://test.api.solvimon.com/v1/pricing-plan-subscriptions/init \
> -H "X-API-KEY: <apiKey>" \
> -H "Content-Type: application/json" \
> -d '{
> "customer": {
> "reference": "cust_1",
> "type": "INDIVIDUAL",
> "email": "john.doe@gmail.com",
> "roles": ["DEFAULT"],
> "individual": {
> "name": {
> "first_name": "John",
> "last_name": "Doe"
> },
> "residential_address": {
> "country": "NL"
> }
> },
> "custom_fields": [
> {
> "reference": "PAYMENT_GATEWAY:ADYEN:SHOPPER_REFERENCE",
> "value": "cust_1"
> }
> ]
> },
> "pricing_plan_subscription": {
> "reference": "cust_1_monthly_eur_20240915",
> "billing_entity_reference": "entity_nl",
> "billing_time": "EXACT",
> "billing_currency": "EUR"
> },
> "pricing_plan_schedules": [
> {
> "pricing_plan_version_selector": {
> "pricing_plan_reference": "monthly_eur"
> },
> "start_at": "2024-09-15T00:00:00Z",
> "end_at": "2025-09-15T00:00:00Z"
> }
> ],
> "first_payment": {
> "payment_acceptor_reference": "adyen_b2c_subscriptions",
> "external_reference": "N9KKLBTLMJS8F6V5",
> "amount": {
> "quantity": "9.99",
> "currency": "EUR"
> },
> "result": "AUTHORIZED"
> },
> "payment_method": {
> "type": "CARD",
> "card": {
> "brand": "VISA",
> "last_four_digits": "1111"
> },
> "integration_reference": "adyen",
> "integration_details": {
> "payment_gateway_variant": "ADYEN",
> "adyen": {
> "recurring_detail_reference": "WC43X3RL9ZD3LTT5"
> }
> }
> }
> }'

Note that customer_reference is omitted from pricing_plan_subscription — the customer is identified via the customer.reference field instead. If a customer with that reference already exists, it will be updated.


Step 4: Handle invoice and payment webhooks

Solvimon calls your endpoint when invoices and payments change state. Configure a webhook under Settings → Webhooks.

For a B2C subscription, handle these two events:

EventWhen it firesWhat to do
invoice.finalizedInvoice status moves to FINALSend a receipt, confirm the billing period in your system
payment.createdA payment attempt is madeCheck result — provision access on success, suspend on failure

You can use a single webhook endpoint for both events.

📘 See the Webhooks guide for payload shapes and verification.


Step 5: Manage the subscription over time

Cancel at period end — set end_at on the current schedule:

$curl -X PATCH https://test.api.solvimon.com/v1/pricing-plan-schedules/<schedule_id> \
> -H "X-API-KEY: <apiKey>" \
> -H "Content-Type: application/json" \
> -d '{
> "end_at": "2025-09-15T00:00:00Z"
> }'

Upgrade to a new plan — add a second schedule starting at the changeover date:

$curl -X POST https://test.api.solvimon.com/v1/pricing-plan-schedules \
> -H "X-API-KEY: <apiKey>" \
> -H "Content-Type: application/json" \
> -d '{
> "pricing_plan_subscription_reference": "cust_1_monthly_eur_20240915",
> "pricing_plan_version_selector": {
> "pricing_plan_reference": "new_plan_reference"
> },
> "start_at": "2025-09-15T00:00:00Z"
> }'

Update the payment method — patch the subscription with the new payment_method_id when a customer updates their card. The updated method will be used for all subsequent invoices.