By: Gourav Bais
SaaS platforms and online marketplaces have revolutionized the way businesses operate. While SaaS platforms provide cloud-based solutions, marketplaces connect buyers and sellers within a shared ecosystem. Both models rely on a strong partner ecosystem, where third-party businesses, service providers, and merchants collaborate to deliver value to their customers. This ecosystem supports tasks like onboarding, revenue models, and payment processes.
However, managing payments across these networks can be challenging due to fragmented systems, regulatory issues, and cross-border complexities. To address these challenges, businesses need a reliable payment infrastructure that supports global operations and ensures smooth transactions. It’s possible to establish this infrastructure manually following a partner model or to opt for a reliable payment solution like Rapyd. Rapyd offers a flexible API and partner-friendly infrastructure, enabling you to create tailored payment experiences, onboard merchants, and automate payouts, all while avoiding the complexities of cross-border payments.
This article introduces some different partner payment models and explains the main components of an effective partner payment flow. You’ll then learn how to implement partner-based payment with Rapyd and Python.
Partner Models for Payments
When businesses expand to support multiple merchants, service providers, or third-party vendors, they should have their payment system designed in a way that will ensure seamless transactions across the ecosystem. Partner payment models help businesses manage these complex financial interactions since they often support handling customer payments, distributing payments to merchants, and splitting revenue with partners.
Businesses using SaaS or marketplaces often integrate partner payment models to manage transactions and compliance. These models can greatly simplify the effort of handling challenges like regulatory compliance, fraud prevention, and operational complexity. Two common models are independent sales organization (ISO) and payment facilitator (PayFac).
- An ISO is a third-party company that resells credit card processing from established providers but doesn’t process payments directly.
- The PayFac model, also known as payment aggregation, involves a third party acting as a merchant of record. In other words, it processes transactions for sub-merchants under a single master account. This model includes payment processing, risk management, and fraud prevention.
Key Components of a Partner Payment Flow
If you want to implement and use a partner payment flow, you need a strong understanding of its key components. An effective partner payment system involves:
- Partner onboarding
- Revenue sharing and tracking
- Compliance and taxation considerations
Partner Onboarding
Partner onboarding is the first step for integrating merchants, vendors, or service providers into a payment system. The process begins with verifying their identity, then setting up their accounts and enabling transactions. A smooth onboarding process can help minimize drop-off rates and ensure that partners can quickly start using the platform. For example, the Rapyd Partner Portal streamlines this process by offering automated registration and verification, ensuring compliance with Know Your Customer (KYC) and Anti-Money Laundering (AML) requirements, and providing tools for partners to track transactions, monitor payouts, and manage accounts from a single interface.
Revenue Sharing and Tracking
Once onboarding is complete, you’ll need to share revenue and track payments. This is particularly important, as you’ll probably be owed an agreed percentage of each partner transaction. A payment platform should support automated revenue splits based on pre-agreed models, real-time tracking of earnings, transaction history, payout schedules, and commission breakdowns. It should also offer flexible payout options, such as instant, scheduled, or milestone-based payments, and support multicurrency payments to reduce conversion fees. A few common revenue-sharing models include equal split, royalty-based, percentage of gross revenue, and percentage of net revenue.
Compliance and Taxation Considerations
Handling payments at scale requires compliance with financial regulations and tax obligations across different regions. Compliance is nonnegotiable in partner payments and ensures that businesses and their partners operate legally and avoid financial penalties. This involves verifying partner identities, monitoring transactions for suspicious activity, and, depending on the jurisdiction, withholding taxes and reporting earnings to tax authorities. Additionally, payment flows must adhere to PCI DSS standards to protect sensitive financial data and comply with privacy regulations like GDPR and CCPA.
Implementing a Partner-Based Payment System with Rapyd and Python
As you can see, manually managing partner payments can become quite a complex and time-consuming task. Rapyd’s payment solution can simplify partner payments for SaaS platforms, marketplaces, and fintech businesses. It supports multiple currencies and handles issues like banking restrictions, currency conversion, and varying country regulations. It also provides built-in compliance tools for automated KYC verification, fraud detection, and adherence to tax compliance. For developers, Rapyd provides easy integration with RESTful APIs and SDKs in languages like Python, Node.js, and Java.
Let’s look at how to use Rapyd to build a simple system where you can onboard merchants, add products, receive payments, and receive payouts, all powered by Rapyd’s API. To fully integrate this system, businesses can sign up as a Rapyd partner to access additional capabilities for managing merchant transactions. In this tutorial, you’ll see how to use the FastAPI framework in Python to create endpoints for each step: onboarding merchants, adding products, receiving payments, and receiving payouts.
Prerequisites
Before you start, you’ll need a working Rapyd Client Portal account to set up a sandbox environment for testing payments. Once you’re logged in, you can get your access key and secret key under the API credentials section in the Client Portal. You’ll need these later.
You’ll also need to have Python installed. Any version 3.8 or later will work for this tutorial.
Create a Python app
Before you begin, install the necessary Python dependencies with this command:
pip install fastapi uvicorn requests
Create a project folder to store all your development scripts. Inside this folder, create a new Python file called merchant_rapyd_app.py
.
In merchant_rapyd_app.py
, first import the necessary Python dependencies as follows:
from fastapi import FastAPI, HTTPException
import requests
import uuid
import hashlib
import hmac
import time
import json
import base64
Once the imports are ready, initialize the FastAPI app and define some dummy databases for merchants, products, payments, and payouts:
app = FastAPI()
# Dummy database
merchants = {}
products = {}
payments = {}
payouts = {}
To connect to the Rapyd API, define your credentials as follows, making sure to replace the placeholders with your actual access key and secret key:
RAPYD_ACCESS_KEY = "YOUR_ACCESS_KEY"
RAPYD_SECRET_KEY = "YOUR_SECRET_KEY"
RAPYD_BASE_URL = "https://sandboxapi.rapyd.net"
Then, define a function named generate_rapyd_headers
that will generate the necessary headers for making the authenticated requests to the Rapyd payment platform:
# Utility function to generate Rapyd headers
def generate_rapyd_headers(http_method, path, body):
timestamp = str(int(time.time()))
salt = str(uuid.uuid4())
body_string = json.dumps(body) if body else ""
to_sign = http_method + path + salt + timestamp + RAPYD_ACCESS_KEY + RAPYD_SECRET_KEY + body_string
signature = base64.b64encode(hmac.new(RAPYD_SECRET_KEY.encode(), to_sign.encode(), hashlib.sha256).digest()).decode()
return {
"Content-Type": "application/json",
"access_key": RAPYD_ACCESS_KEY,
"salt": salt,
"timestamp": timestamp,
"signature": signature
}
The above code helps you interact securely with Rapyd’s API, where each request must be authenticated using a signature-based mechanism. Here:
timestamp
saves the current UNIX time (in seconds). Rapyd requires a valid timestamp to ensure that the request is fresh and prevent replay attacks.salt
is a randomly generated unique identifier (UUID). This makes sure that each request is unique and adds an extra layer of security.body_string
represents the request payload, which is converted to a JSON string. If there is no request body, it will remain an empty string.to_sign
is a concatenation of the HTTP method, request path, salt, timestamp, access key, secret key, and body content. This string is what you sign to generate the authentication signature.- The
hmac.new()
function creates a cryptographic hash-based message authentication code (HMAC) using the SHA-256 hashing algorithm. It signs theto_sign
string with theRAPYD_SECRET_KEY
, ensuring that people with a secret key can generate valid signatures. - The HMAC result is always a binary output, so you need
base64.b64encode
to encode it to Base64 and make it a readable string, which is suitable for transmissions in HTTP headers.
Create an Endpoint for Merchant Onboarding
The first stage in the partner payment solution is to onboard a merchant. Each merchant should have a unique ID that identifies them.
Create an endpoint for merchant onboarding:
@app.post("/merchant/register")
def register_merchant(name: str):
merchant_id = str(uuid.uuid4())
merchants[merchant_id] = {"name": name, "balance": 0.0}
return {"merchant_id": merchant_id, "message": "Merchant registered successfully"}
The merchant IDs are generated using the uuid
module. These unique IDs ensure there are no conflicts or duplications when processing transactions and are essential for managing merchant-specific payments and payouts.
This is just a basic example; onboarding a merchant is a far more detailed process and can also involve KYC steps. But don’t worry—Rapyd has a product called Rapyd Verify to help with that as well.
Create an Endpoint for Adding a Product
Once the merchant is onboarded, it can list products for customers to buy. To enable this, create an endpoint where merchants can add products:
@app.post("/merchant/{merchant_id}/add_product")
def add_product(merchant_id: str, name: str, price: float):
if merchant_id not in merchants:
raise HTTPException(status_code=404, detail="Merchant not found")
product_id = str(uuid.uuid4())
products[product_id] = {"merchant_id": merchant_id, "name": name, "price": price}
return {"product_id": product_id, "message": "Product added successfully"}
As you can see, the product is linked to the merchant. This ensures that when multiple customers make purchases simultaneously, each product is correctly associated with the right merchant, avoiding payment confusion. This example is only a simplified version; in real-world applications, products will likely include additional details such as descriptions, categories, stock levels, and images to provide a rich customer experience.
Create an Endpoint to Receive Payments Using Rapyd
Once a customer purchases something, the next step is to forward them to an endpoint where they can complete the payment for the product they’re buying from the merchant. To process the payment, you need to integrate with the Rapyd API, which will handle the transaction. This example uses a card payment method with the currency set to USD. Before proceeding, you need to enable the Card Payment API for payments and payouts:
@app.post("/pay/{product_id}")
def collect_payment(
product_id: str,
currency: str,
payment_method: str,
platform_fee_percentage: float = 10.0 # Default fee is 10%
):
if product_id not in products:
raise HTTPException(status_code=404, detail="Product not found")
product = products[product_id]
merchant_id = product["merchant_id"]
amount = product["price"]
# Validate platform fee percentage (should be between 0% and 100%)
if not (0 <= platform_fee_percentage <= 100):
raise HTTPException(status_code=400, detail="Invalid platform fee percentage")
# Convert percentage to decimal
platform_fee_decimal = platform_fee_percentage / 100
# Calculate platform fee and merchant payout
platform_fee = amount * platform_fee_decimal
merchant_payout = amount - platform_fee # Amount merchant receives
# Prepare payment data for Rapyd API
payment_data = {
"amount": amount,
"currency": currency,
"payment_method": payment_method,
"description": f"Payment for {product['name']}"
}
headers = generate_rapyd_headers("post", "/v1/payments", payment_data)
response = requests.post(f"{RAPYD_BASE_URL}/v1/payments", json=payment_data, headers=headers)
if response.status_code != 200:
raise HTTPException(status_code=500, detail="Failed to create payment")
payment_response = response.json()
payment_id = payment_response.get("id")
# Store payment record
payments[payment_id] = {
"merchant_id": merchant_id,
"amount": amount,
"platform_fee": platform_fee,
"merchant_payout": merchant_payout
}
# Update merchant balance
merchants[merchant_id]["balance"] += merchant_payout
return {
"payment_id": payment_id,
"platform_fee_percentage": platform_fee_percentage,
"platform_fee": platform_fee,
"merchant_payout": merchant_payout,
"message": "Payment successful"
}
The endpoint initiates the payment for the selected products. You might notice that platform_fee_percentage
is a requested parameter (10 percent by default) that allows merchants or platform admins to set a custom percentage for the platform fee for each transaction. This allows them to customize the fee based on factors such as transaction type (card-based vs. non-card transactions), debit vs. credit cards, merchant category code, and commercial vs. consumer cards to determine the right platform cost based on the transaction overheads and risks. This fee is then deducted from the total product amount, and the remaining amount is updated in the merchant’s balance.
It’s possible for the client to disconnect after the API request is initiated but before a response can be received. This would mean that the payment is processed, but since the client (ie the Python app) doesn’t know about it, the purchase will fail. In such situations, webhooks can help by sending a callback message to your app every time a payment is processed. In a real-world app, you must implement these to make your payments reliable.
Create an Endpoint to Automate Merchant Payouts
Finally, once the payment is successful, merchants should be able to withdraw their funds using the Rapyd payout system. To implement this functionality, create the final endpoint as follows:
@app.post("/merchant/{merchant_id}/payout")
def payout_merchant(merchant_id: str):
if merchant_id not in merchants:
raise HTTPException(status_code=404, detail="Merchant not found")
balance = merchants[merchant_id]["balance"]
if balance <= 0:
raise HTTPException(status_code=400, detail="No funds available for payout")
payout_data = {
"amount": balance,
"currency": "USD",
"payout_method_type": "bank_transfer",
"sender_currency": "USD",
"beneficiary": {"name": merchants[merchant_id]["name"]}
}
headers = generate_rapyd_headers("post", "/v1/payouts", payout_data)
response = requests.post(f"{RAPYD_BASE_URL}/v1/payouts", json=payout_data, headers=headers)
if response.status_code != 200:
raise HTTPException(status_code=500, detail="Failed to process payout")
payout_response = response.json()
payout_id = payout_response.get("id")
payouts[payout_id] = {"merchant_id": merchant_id, "amount": balance}
merchants[merchant_id]["balance"] = 0
return {"payout_id": payout_id, "message": "Payout successful"}
This endpoint allows you to pay merchants without having to worry about manually calculating their earnings and initiating transfers for those amounts. Moreover, it also automates compliance with payout regulations.
Run the App
That’s it! You’ve just created a partner payments solution where merchants can be onboarded and add products, and customers can make payments for purchased products using Rapyd. The next step is to run your app and test the endpoints.
To run the app, open a command prompt and run the merchant_rapyd_app.py
file as follows:
uvicorn merchant_rapyd_app:app --host 0.0.0.0 --port 8000 --reload
This will start your application, which you can access in your browser at http://localhost:8000/docs
:
Feel free to test the endpoints that you’ve created with curl
commands.
This command registers the merchant and creates a new merchant account:
curl -X POST "http://localhost:8000/merchant/register?name=John's%20Store"
{ "merchant_id": "550e8400-e29b-41d4-a716-446655440000", "message": "Merchant registered successfully" }
Save this merchant ID for additional tests.
List a product for the merchant (with the appropriate merchant ID) using the following command:
curl -X POST "http://localhost:8000/merchant/550e8400-e29b-41d4-a716-446655440000/add_product?name=Wireless%20Headphones&price=50.0"
{ "product_id": "c1a7f2d5-3e3a-49c6-bc15-22a5dc5e2a80", "message": "Product added successfully" }
Save this product ID for the next test.
Payment processing should happen as soon as the customer buys a product. You can test this with the following endpoint hit (using the product ID):
curl curl -X POST "http://localhost:8000/pay/c1a7f2d5-3e3a-49c6-bc15-22a5dc5e2a80?currency=USD&payment_method=card&platform_fee_percentage=10.0"
{ "payment_id": "pay_12345", "platform_fee_percentage": 10.0, "platform_fee": 5.0, "merchant_payout": 45.0, "message": "Payment successful" }
Since you set the platform fee to 10 percent, it’s deducted from the total product amount, and the remaining amount is reflected in the merchant payout. The payment ID is useful for tracking payments.
Finally, test the merchant payout with the following command:
curl -X POST "http://localhost:8000/merchant/550e8400-e29b-41d4-a716-446655440000/payout"
{ "payout_id": "payout_567e4567-e89b-12d3-a456-426614174003", "message": "Payout successful" }
You can access the full code in this GitHub repo.
Conclusion
After reading this article, you now know how to implement a partner-based payment system using Rapyd. You’ve explored various partner models (ISO and PayFac), the key components of a partner payment flow, and a step-by-step guide to building a payment solution with Rapyd and Python.
Rapyd offers a simplified solution for payment processing that makes it easier for SaaS platforms, marketplaces, and fintech businesses to onboard partners, receive payments, and automate revenue sharing. Ready to integrate Rapyd into your platform? Sign up for a free Rapyd account and check out the Rapyd API documentation.