# First, generate JWT token (use script or online tool)
TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
curl -X POST https://kyc.sbx.moduluslabs.io/v2/onboard \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"businessType": "STARTER",
"merchantName": "Starbucks",
"modeOfPayments": ["ECOM"],
"currency": "PHP",
"tin": "455691852",
"industry": "Food and Beverage",
"serviceDescription": "Specialty coffee retailer",
"isBrickAndMortarStore": true,
"address": {
"office": {
"city": "Portland",
"line1": "111 Clarence Basler Rd",
"state": "Oregon(OR)",
"postalCode": "97030",
"contactNumber": "639865748123",
"barangay": "Wilmington II"
}
},
"representatives": {
"authorized": {
"firstName": "David",
"lastName": "Haven",
"emailAddress": "david@haven.com",
"contactNumber": "09789364458",
"dateOfBirth": "1988-02-12T16:00:00.000Z",
"position": "Accountant"
}
},
"banks": [
{
"accountDepositType": "GCASH",
"bankName": "GCASH",
"accountName": "Starbucks Corporation",
"accountNumber": "09260000000"
}
]
}'
const axios = require('axios');
const jwt = require('jsonwebtoken');
const SECRET_KEY = process.env.MODULUS_ONBOARDING_SECRET_KEY;
// Generate JWT token
function generateToken(accountId, email) {
return jwt.sign({ sub: accountId, email }, SECRET_KEY, { algorithm: 'HS256' });
}
// Onboard merchant
async function onboardMerchant() {
const token = generateToken(1, 'merchant@gmail.com');
const merchantData = {
businessType: 'STARTER',
legalName: 'Starbucks',
merchantName: 'Starbucks',
modeOfPayments: ['ECOM'],
currency: 'PHP',
tin: '455691852',
industry: 'Food and Beverage',
serviceDescription: 'Specialty coffee retailer',
isBrickAndMortarStore: true,
address: {
office: {
city: 'Portland',
line1: '111 Clarence Basler Rd',
buildingNameAndNumber: 'Gresham Hub',
state: 'Oregon(OR)',
postalCode: '97030',
contactNumber: '639865748123',
barangay: 'Wilmington II'
}
},
websites: {
businessWebsiteUrl: 'https://www.starbucks.com/',
isBusinessWebsiteUnderDevelopment: false
},
representatives: {
authorized: {
firstName: 'David',
middleName: 'Reese',
lastName: 'Haven',
emailAddress: 'david@haven.com',
contactNumber: '09789364458',
dateOfBirth: '1988-02-12T16:00:00.000Z',
position: 'Accountant'
}
},
banks: [
{
accountDepositType: 'GCASH',
bankName: 'GCASH',
accountName: 'Starbucks Corporation',
accountNumber: '09260000000'
},
{
accountDepositType: 'BANK',
accountType: 'SAVINGS',
bankName: 'ASIA_UNITED_BANK',
accountName: 'Starbucks Corporation',
accountNumber: '4716542700323890',
currency: 'PHP'
}
]
};
try {
const response = await axios.post(
'https://kyc.sbx.moduluslabs.io/v2/onboard',
merchantData,
{
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
}
);
console.log(' Merchant onboarded successfully');
console.log('Reference Number:', response.data.referenceNumber);
return response.data;
} catch (error) {
console.error(' Onboarding failed:', error.response?.data || error.message);
throw error;
}
}
onboardMerchant();
import os
import requests
import jwt
SECRET_KEY = os.getenv('MODULUS_ONBOARDING_SECRET_KEY')
def generate_token(account_id, email):
"""Generate JWT token"""
return jwt.encode(
{'sub': account_id, 'email': email},
SECRET_KEY,
algorithm='HS256'
)
def onboard_merchant():
"""Onboard a merchant"""
token = generate_token(1, 'merchant@gmail.com')
merchant_data = {
'businessType': 'STARTER',
'legalName': 'Starbucks',
'merchantName': 'Starbucks',
'modeOfPayments': ['ECOM'],
'currency': 'PHP',
'tin': '455691852',
'industry': 'Food and Beverage',
'serviceDescription': 'Specialty coffee retailer',
'isBrickAndMortarStore': True,
'address': {
'office': {
'city': 'Portland',
'line1': '111 Clarence Basler Rd',
'buildingNameAndNumber': 'Gresham Hub',
'state': 'Oregon(OR)',
'postalCode': '97030',
'contactNumber': '639865748123',
'barangay': 'Wilmington II'
}
},
'representatives': {
'authorized': {
'firstName': 'David',
'middleName': 'Reese',
'lastName': 'Haven',
'emailAddress': 'david@haven.com',
'contactNumber': '09789364458',
'dateOfBirth': '1988-02-12T16:00:00.000Z',
'position': 'Accountant'
}
},
'banks': [
{
'accountDepositType': 'GCASH',
'bankName': 'GCASH',
'accountName': 'Starbucks Corporation',
'accountNumber': '09260000000'
}
]
}
try:
response = requests.post(
'https://kyc.sbx.moduluslabs.io/v2/onboard',
json=merchant_data,
headers={
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
)
response.raise_for_status()
print(' Merchant onboarded successfully')
print(f"Reference Number: {response.json()['referenceNumber']}")
return response.json()
except requests.exceptions.HTTPError as e:
print(f' Onboarding failed: {e.response.text}')
raise
if __name__ == '__main__':
onboard_merchant()
<?php
require 'vendor/autoload.php'; // composer require firebase/php-jwt guzzlehttp/guzzle
use Firebase\JWT\JWT;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
$secretKey = getenv('MODULUS_ONBOARDING_SECRET_KEY');
/**
* Generate JWT token
*/
function generateToken($accountId, $email, $secretKey) {
$payload = [
'sub' => $accountId,
'email' => $email
];
return JWT::encode($payload, $secretKey, 'HS256');
}
/**
* Onboard a merchant
*/
function onboardMerchant() {
global $secretKey;
$token = generateToken(1, 'merchant@gmail.com', $secretKey);
$merchantData = [
'businessType' => 'STARTER',
'legalName' => 'Starbucks',
'merchantName' => 'Starbucks',
'modeOfPayments' => ['ECOM'],
'currency' => 'PHP',
'tin' => '455691852',
'industry' => 'Food and Beverage',
'serviceDescription' => 'Specialty coffee retailer',
'isBrickAndMortarStore' => true,
'address' => [
'office' => [
'city' => 'Portland',
'line1' => '111 Clarence Basler Rd',
'buildingNameAndNumber' => 'Gresham Hub',
'state' => 'Oregon(OR)',
'postalCode' => '97030',
'contactNumber' => '639865748123',
'barangay' => 'Wilmington II'
]
],
'websites' => [
'businessWebsiteUrl' => 'https://www.starbucks.com/',
'isBusinessWebsiteUnderDevelopment' => false
],
'representatives' => [
'authorized' => [
'firstName' => 'David',
'middleName' => 'Reese',
'lastName' => 'Haven',
'emailAddress' => 'david@haven.com',
'contactNumber' => '09789364458',
'dateOfBirth' => '1988-02-12T16:00:00.000Z',
'position' => 'Accountant'
]
],
'banks' => [
[
'accountDepositType' => 'GCASH',
'bankName' => 'GCASH',
'accountName' => 'Starbucks Corporation',
'accountNumber' => '09260000000'
],
[
'accountDepositType' => 'BANK',
'accountType' => 'SAVINGS',
'bankName' => 'ASIA_UNITED_BANK',
'accountName' => 'Starbucks Corporation',
'accountNumber' => '4716542700323890',
'currency' => 'PHP'
]
]
];
try {
$client = new Client();
$response = $client->post('https://kyc.sbx.moduluslabs.io/v2/onboard', [
'headers' => [
'Authorization' => 'Bearer ' . $token,
'Content-Type' => 'application/json'
],
'json' => $merchantData
]);
$body = json_decode($response->getBody(), true);
echo " Merchant onboarded successfully\n";
echo "Reference Number: " . $body['referenceNumber'] . "\n";
return $body;
} catch (RequestException $e) {
echo " Onboarding failed: " . $e->getMessage() . "\n";
if ($e->hasResponse()) {
echo $e->getResponse()->getBody() . "\n";
}
throw $e;
}
}
onboardMerchant();
?>
import com.google.gson.Gson;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import okhttp3.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.security.Key;
import java.util.*;
public class OnboardMerchant {
private static final String SECRET_KEY = System.getenv("MODULUS_ONBOARDING_SECRET_KEY");
private static final String API_URL = "https://kyc.sbx.moduluslabs.io/v2/onboard";
private static final MediaType JSON = MediaType.get("application/json; charset=utf-8");
/**
* Generate JWT token
*/
public static String generateToken(int accountId, String email) {
Key key = new SecretKeySpec(SECRET_KEY.getBytes(), SignatureAlgorithm.HS256.getJcaName());
return Jwts.builder()
.claim("sub", accountId)
.claim("email", email)
.signWith(key, SignatureAlgorithm.HS256)
.compact();
}
/**
* Onboard a merchant
*/
public static void onboardMerchant() throws IOException {
String token = generateToken(1, "merchant@gmail.com");
// Create merchant data
Map<String, Object> merchantData = new HashMap<>();
merchantData.put("businessType", "STARTER");
merchantData.put("legalName", "Starbucks");
merchantData.put("merchantName", "Starbucks");
merchantData.put("modeOfPayments", Arrays.asList("ECOM"));
merchantData.put("currency", "PHP");
merchantData.put("tin", "455691852");
merchantData.put("industry", "Food and Beverage");
merchantData.put("serviceDescription", "Specialty coffee retailer");
merchantData.put("isBrickAndMortarStore", true);
// Address
Map<String, Object> office = new HashMap<>();
office.put("city", "Portland");
office.put("line1", "111 Clarence Basler Rd");
office.put("buildingNameAndNumber", "Gresham Hub");
office.put("state", "Oregon(OR)");
office.put("postalCode", "97030");
office.put("contactNumber", "639865748123");
office.put("barangay", "Wilmington II");
Map<String, Object> address = new HashMap<>();
address.put("office", office);
merchantData.put("address", address);
// Websites
Map<String, Object> websites = new HashMap<>();
websites.put("businessWebsiteUrl", "https://www.starbucks.com/");
websites.put("isBusinessWebsiteUnderDevelopment", false);
merchantData.put("websites", websites);
// Representatives
Map<String, Object> authorized = new HashMap<>();
authorized.put("firstName", "David");
authorized.put("middleName", "Reese");
authorized.put("lastName", "Haven");
authorized.put("emailAddress", "david@haven.com");
authorized.put("contactNumber", "09789364458");
authorized.put("dateOfBirth", "1988-02-12T16:00:00.000Z");
authorized.put("position", "Accountant");
Map<String, Object> representatives = new HashMap<>();
representatives.put("authorized", authorized);
merchantData.put("representatives", representatives);
// Banks
Map<String, Object> bank1 = new HashMap<>();
bank1.put("accountDepositType", "GCASH");
bank1.put("bankName", "GCASH");
bank1.put("accountName", "Starbucks Corporation");
bank1.put("accountNumber", "09260000000");
Map<String, Object> bank2 = new HashMap<>();
bank2.put("accountDepositType", "BANK");
bank2.put("accountType", "SAVINGS");
bank2.put("bankName", "ASIA_UNITED_BANK");
bank2.put("accountName", "Starbucks Corporation");
bank2.put("accountNumber", "4716542700323890");
bank2.put("currency", "PHP");
merchantData.put("banks", Arrays.asList(bank1, bank2));
// Send request
Gson gson = new Gson();
String json = gson.toJson(merchantData);
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(json, JSON);
Request request = new Request.Builder()
.url(API_URL)
.header("Authorization", "Bearer " + token)
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
String responseBody = response.body().string();
if (response.isSuccessful()) {
System.out.println(" Merchant onboarded successfully");
System.out.println("Response: " + responseBody);
} else {
System.out.println(" Onboarding failed: HTTP " + response.code());
System.out.println("Details: " + responseBody);
}
}
}
public static void main(String[] args) {
try {
onboardMerchant();
} catch (IOException e) {
System.err.println(" Error: " + e.getMessage());
e.printStackTrace();
}
}
}
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
"github.com/golang-jwt/jwt/v5"
)
const apiURL = "https://kyc.sbx.moduluslabs.io/v2/onboard"
// generateToken creates a JWT token
func generateToken(accountID int, email, secretKey string) (string, error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"sub": accountID,
"email": email,
})
return token.SignedString([]byte(secretKey))
}
// onboardMerchant sends the onboarding request
func onboardMerchant() error {
secretKey := os.Getenv("MODULUS_ONBOARDING_SECRET_KEY")
if secretKey == "" {
return fmt.Errorf("MODULUS_ONBOARDING_SECRET_KEY environment variable not set")
}
token, err := generateToken(1, "merchant@gmail.com", secretKey)
if err != nil {
return fmt.Errorf("failed to generate token: %w", err)
}
merchantData := map[string]interface{}{
"businessType": "STARTER",
"legalName": "Starbucks",
"merchantName": "Starbucks",
"modeOfPayments": []string{"ECOM"},
"currency": "PHP",
"tin": "455691852",
"industry": "Food and Beverage",
"serviceDescription": "Specialty coffee retailer",
"isBrickAndMortarStore": true,
"address": map[string]interface{}{
"office": map[string]interface{}{
"city": "Portland",
"line1": "111 Clarence Basler Rd",
"buildingNameAndNumber": "Gresham Hub",
"state": "Oregon(OR)",
"postalCode": "97030",
"contactNumber": "639865748123",
"barangay": "Wilmington II",
},
},
"websites": map[string]interface{}{
"businessWebsiteUrl": "https://www.starbucks.com/",
"isBusinessWebsiteUnderDevelopment": false,
},
"representatives": map[string]interface{}{
"authorized": map[string]interface{}{
"firstName": "David",
"middleName": "Reese",
"lastName": "Haven",
"emailAddress": "david@haven.com",
"contactNumber": "09789364458",
"dateOfBirth": "1988-02-12T16:00:00.000Z",
"position": "Accountant",
},
},
"banks": []map[string]interface{}{
{
"accountDepositType": "GCASH",
"bankName": "GCASH",
"accountName": "Starbucks Corporation",
"accountNumber": "09260000000",
},
{
"accountDepositType": "BANK",
"accountType": "SAVINGS",
"bankName": "ASIA_UNITED_BANK",
"accountName": "Starbucks Corporation",
"accountNumber": "4716542700323890",
"currency": "PHP",
},
},
}
jsonData, err := json.Marshal(merchantData)
if err != nil {
return fmt.Errorf("failed to marshal data: %w", err)
}
req, err := http.NewRequest("POST", apiURL, bytes.NewBuffer(jsonData))
if err != nil {
return fmt.Errorf("failed to create request: %w", err)
}
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
resp, err := client.Do(req)
if err != nil {
return fmt.Errorf("request failed: %w", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("failed to read response: %w", err)
}
if resp.StatusCode == http.StatusOK {
var result map[string]interface{}
if err := json.Unmarshal(body, &result); err != nil {
return fmt.Errorf("failed to parse response: %w", err)
}
fmt.Println(" Merchant onboarded successfully")
fmt.Printf("Reference Number: %s\n", result["referenceNumber"])
return nil
}
fmt.Printf(" Onboarding failed: HTTP %d\n", resp.StatusCode)
fmt.Printf("Details: %s\n", string(body))
return fmt.Errorf("onboarding failed with status %d", resp.StatusCode)
}
func main() {
if err := onboardMerchant(); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
}
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.IdentityModel.Tokens.Jwt; // Install-Package System.IdentityModel.Tokens.Jwt
using Microsoft.IdentityModel.Tokens;
class Program
{
static async Task Main(string[] args)
{
await OnboardMerchant();
}
static string GenerateToken(int accountId, string email, string secretKey)
{
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.UTF8.GetBytes(secretKey);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new System.Security.Claims.ClaimsIdentity(new[]
{
new System.Security.Claims.Claim("sub", accountId.ToString()),
new System.Security.Claims.Claim("email", email)
}),
SigningCredentials = new SigningCredentials(
new SymmetricSecurityKey(key),
SecurityAlgorithms.HmacSha256Signature
)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
static async Task OnboardMerchant()
{
// Get secret key from environment variable
var secretKey = Environment.GetEnvironmentVariable("MODULUS_ONBOARDING_SECRET_KEY");
if (string.IsNullOrEmpty(secretKey))
{
Console.WriteLine(" Error: MODULUS_ONBOARDING_SECRET_KEY environment variable not set");
return;
}
// Generate JWT token
var token = GenerateToken(1, "merchant@gmail.com", secretKey);
try
{
// Create HTTP client with Bearer token authentication
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", token);
// Prepare merchant data
var merchantData = new
{
businessType = "STARTER",
legalName = "Starbucks",
merchantName = "Starbucks",
modeOfPayments = new[] { "ECOM" },
currency = "PHP",
tin = "455691852",
industry = "Food and Beverage",
serviceDescription = "Specialty coffee retailer",
isBrickAndMortarStore = true,
address = new
{
office = new
{
city = "Portland",
line1 = "111 Clarence Basler Rd",
buildingNameAndNumber = "Gresham Hub",
state = "Oregon(OR)",
postalCode = "97030",
contactNumber = "639865748123",
barangay = "Wilmington II"
}
},
websites = new
{
businessWebsiteUrl = "https://www.starbucks.com/",
isBusinessWebsiteUnderDevelopment = false
},
representatives = new
{
authorized = new
{
firstName = "David",
middleName = "Reese",
lastName = "Haven",
emailAddress = "david@haven.com",
contactNumber = "09789364458",
dateOfBirth = "1988-02-12T16:00:00.000Z",
position = "Accountant"
}
},
banks = new[]
{
new
{
accountDepositType = "GCASH",
bankName = "GCASH",
accountName = "Starbucks Corporation",
accountNumber = "09260000000"
},
new
{
accountDepositType = "BANK",
accountType = "SAVINGS",
bankName = "ASIA_UNITED_BANK",
accountName = "Starbucks Corporation",
accountNumber = "4716542700323890",
currency = "PHP"
}
}
};
var content = new StringContent(
JsonSerializer.Serialize(merchantData),
Encoding.UTF8,
"application/json"
);
// Send POST request
var response = await client.PostAsync(
"https://kyc.sbx.moduluslabs.io/v2/onboard",
content
);
var responseBody = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
var result = JsonSerializer.Deserialize<OnboardResponse>(
responseBody,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true }
);
Console.WriteLine(" Merchant onboarded successfully");
Console.WriteLine($"Reference Number: {result.ReferenceNumber}");
}
else
{
Console.WriteLine($" Onboarding failed: HTTP {(int)response.StatusCode}");
Console.WriteLine($"Details: {responseBody}");
}
}
catch (HttpRequestException e)
{
Console.WriteLine($" Request failed: {e.Message}");
}
catch (Exception e)
{
Console.WriteLine($" Error: {e.Message}");
}
}
}
// Response model
public class OnboardResponse
{
public string ReferenceNumber { get; set; }
}
{
"referenceNumber": "0a17c362-fe5c-4889-9cb5-47df71dac425"
}
{
"code": "20000004",
"error": "Please upload idsOfValidSignatories file/s before accessing this API.",
"referenceNumber": "02383ca9-8d72-47e2-9dcb-23e535a96122"
}
{
"code": "20000001",
"error": "Invalid or expired JWT token",
"referenceNumber": "097bf60a-bdab-40bf-b615-3c0eae693b86"
}
{
"code": "10000001",
"error": "An unexpected error occurred. Please try again later.",
"referenceNumber": "097bf60a-bdab-40bf-b615-3c0eae693b86"
}
Onboard Merchant
Onboard a merchant to accept payments through Modulus Labs
# First, generate JWT token (use script or online tool)
TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
curl -X POST https://kyc.sbx.moduluslabs.io/v2/onboard \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"businessType": "STARTER",
"merchantName": "Starbucks",
"modeOfPayments": ["ECOM"],
"currency": "PHP",
"tin": "455691852",
"industry": "Food and Beverage",
"serviceDescription": "Specialty coffee retailer",
"isBrickAndMortarStore": true,
"address": {
"office": {
"city": "Portland",
"line1": "111 Clarence Basler Rd",
"state": "Oregon(OR)",
"postalCode": "97030",
"contactNumber": "639865748123",
"barangay": "Wilmington II"
}
},
"representatives": {
"authorized": {
"firstName": "David",
"lastName": "Haven",
"emailAddress": "david@haven.com",
"contactNumber": "09789364458",
"dateOfBirth": "1988-02-12T16:00:00.000Z",
"position": "Accountant"
}
},
"banks": [
{
"accountDepositType": "GCASH",
"bankName": "GCASH",
"accountName": "Starbucks Corporation",
"accountNumber": "09260000000"
}
]
}'
const axios = require('axios');
const jwt = require('jsonwebtoken');
const SECRET_KEY = process.env.MODULUS_ONBOARDING_SECRET_KEY;
// Generate JWT token
function generateToken(accountId, email) {
return jwt.sign({ sub: accountId, email }, SECRET_KEY, { algorithm: 'HS256' });
}
// Onboard merchant
async function onboardMerchant() {
const token = generateToken(1, 'merchant@gmail.com');
const merchantData = {
businessType: 'STARTER',
legalName: 'Starbucks',
merchantName: 'Starbucks',
modeOfPayments: ['ECOM'],
currency: 'PHP',
tin: '455691852',
industry: 'Food and Beverage',
serviceDescription: 'Specialty coffee retailer',
isBrickAndMortarStore: true,
address: {
office: {
city: 'Portland',
line1: '111 Clarence Basler Rd',
buildingNameAndNumber: 'Gresham Hub',
state: 'Oregon(OR)',
postalCode: '97030',
contactNumber: '639865748123',
barangay: 'Wilmington II'
}
},
websites: {
businessWebsiteUrl: 'https://www.starbucks.com/',
isBusinessWebsiteUnderDevelopment: false
},
representatives: {
authorized: {
firstName: 'David',
middleName: 'Reese',
lastName: 'Haven',
emailAddress: 'david@haven.com',
contactNumber: '09789364458',
dateOfBirth: '1988-02-12T16:00:00.000Z',
position: 'Accountant'
}
},
banks: [
{
accountDepositType: 'GCASH',
bankName: 'GCASH',
accountName: 'Starbucks Corporation',
accountNumber: '09260000000'
},
{
accountDepositType: 'BANK',
accountType: 'SAVINGS',
bankName: 'ASIA_UNITED_BANK',
accountName: 'Starbucks Corporation',
accountNumber: '4716542700323890',
currency: 'PHP'
}
]
};
try {
const response = await axios.post(
'https://kyc.sbx.moduluslabs.io/v2/onboard',
merchantData,
{
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
}
);
console.log(' Merchant onboarded successfully');
console.log('Reference Number:', response.data.referenceNumber);
return response.data;
} catch (error) {
console.error(' Onboarding failed:', error.response?.data || error.message);
throw error;
}
}
onboardMerchant();
import os
import requests
import jwt
SECRET_KEY = os.getenv('MODULUS_ONBOARDING_SECRET_KEY')
def generate_token(account_id, email):
"""Generate JWT token"""
return jwt.encode(
{'sub': account_id, 'email': email},
SECRET_KEY,
algorithm='HS256'
)
def onboard_merchant():
"""Onboard a merchant"""
token = generate_token(1, 'merchant@gmail.com')
merchant_data = {
'businessType': 'STARTER',
'legalName': 'Starbucks',
'merchantName': 'Starbucks',
'modeOfPayments': ['ECOM'],
'currency': 'PHP',
'tin': '455691852',
'industry': 'Food and Beverage',
'serviceDescription': 'Specialty coffee retailer',
'isBrickAndMortarStore': True,
'address': {
'office': {
'city': 'Portland',
'line1': '111 Clarence Basler Rd',
'buildingNameAndNumber': 'Gresham Hub',
'state': 'Oregon(OR)',
'postalCode': '97030',
'contactNumber': '639865748123',
'barangay': 'Wilmington II'
}
},
'representatives': {
'authorized': {
'firstName': 'David',
'middleName': 'Reese',
'lastName': 'Haven',
'emailAddress': 'david@haven.com',
'contactNumber': '09789364458',
'dateOfBirth': '1988-02-12T16:00:00.000Z',
'position': 'Accountant'
}
},
'banks': [
{
'accountDepositType': 'GCASH',
'bankName': 'GCASH',
'accountName': 'Starbucks Corporation',
'accountNumber': '09260000000'
}
]
}
try:
response = requests.post(
'https://kyc.sbx.moduluslabs.io/v2/onboard',
json=merchant_data,
headers={
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
)
response.raise_for_status()
print(' Merchant onboarded successfully')
print(f"Reference Number: {response.json()['referenceNumber']}")
return response.json()
except requests.exceptions.HTTPError as e:
print(f' Onboarding failed: {e.response.text}')
raise
if __name__ == '__main__':
onboard_merchant()
<?php
require 'vendor/autoload.php'; // composer require firebase/php-jwt guzzlehttp/guzzle
use Firebase\JWT\JWT;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
$secretKey = getenv('MODULUS_ONBOARDING_SECRET_KEY');
/**
* Generate JWT token
*/
function generateToken($accountId, $email, $secretKey) {
$payload = [
'sub' => $accountId,
'email' => $email
];
return JWT::encode($payload, $secretKey, 'HS256');
}
/**
* Onboard a merchant
*/
function onboardMerchant() {
global $secretKey;
$token = generateToken(1, 'merchant@gmail.com', $secretKey);
$merchantData = [
'businessType' => 'STARTER',
'legalName' => 'Starbucks',
'merchantName' => 'Starbucks',
'modeOfPayments' => ['ECOM'],
'currency' => 'PHP',
'tin' => '455691852',
'industry' => 'Food and Beverage',
'serviceDescription' => 'Specialty coffee retailer',
'isBrickAndMortarStore' => true,
'address' => [
'office' => [
'city' => 'Portland',
'line1' => '111 Clarence Basler Rd',
'buildingNameAndNumber' => 'Gresham Hub',
'state' => 'Oregon(OR)',
'postalCode' => '97030',
'contactNumber' => '639865748123',
'barangay' => 'Wilmington II'
]
],
'websites' => [
'businessWebsiteUrl' => 'https://www.starbucks.com/',
'isBusinessWebsiteUnderDevelopment' => false
],
'representatives' => [
'authorized' => [
'firstName' => 'David',
'middleName' => 'Reese',
'lastName' => 'Haven',
'emailAddress' => 'david@haven.com',
'contactNumber' => '09789364458',
'dateOfBirth' => '1988-02-12T16:00:00.000Z',
'position' => 'Accountant'
]
],
'banks' => [
[
'accountDepositType' => 'GCASH',
'bankName' => 'GCASH',
'accountName' => 'Starbucks Corporation',
'accountNumber' => '09260000000'
],
[
'accountDepositType' => 'BANK',
'accountType' => 'SAVINGS',
'bankName' => 'ASIA_UNITED_BANK',
'accountName' => 'Starbucks Corporation',
'accountNumber' => '4716542700323890',
'currency' => 'PHP'
]
]
];
try {
$client = new Client();
$response = $client->post('https://kyc.sbx.moduluslabs.io/v2/onboard', [
'headers' => [
'Authorization' => 'Bearer ' . $token,
'Content-Type' => 'application/json'
],
'json' => $merchantData
]);
$body = json_decode($response->getBody(), true);
echo " Merchant onboarded successfully\n";
echo "Reference Number: " . $body['referenceNumber'] . "\n";
return $body;
} catch (RequestException $e) {
echo " Onboarding failed: " . $e->getMessage() . "\n";
if ($e->hasResponse()) {
echo $e->getResponse()->getBody() . "\n";
}
throw $e;
}
}
onboardMerchant();
?>
import com.google.gson.Gson;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import okhttp3.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.security.Key;
import java.util.*;
public class OnboardMerchant {
private static final String SECRET_KEY = System.getenv("MODULUS_ONBOARDING_SECRET_KEY");
private static final String API_URL = "https://kyc.sbx.moduluslabs.io/v2/onboard";
private static final MediaType JSON = MediaType.get("application/json; charset=utf-8");
/**
* Generate JWT token
*/
public static String generateToken(int accountId, String email) {
Key key = new SecretKeySpec(SECRET_KEY.getBytes(), SignatureAlgorithm.HS256.getJcaName());
return Jwts.builder()
.claim("sub", accountId)
.claim("email", email)
.signWith(key, SignatureAlgorithm.HS256)
.compact();
}
/**
* Onboard a merchant
*/
public static void onboardMerchant() throws IOException {
String token = generateToken(1, "merchant@gmail.com");
// Create merchant data
Map<String, Object> merchantData = new HashMap<>();
merchantData.put("businessType", "STARTER");
merchantData.put("legalName", "Starbucks");
merchantData.put("merchantName", "Starbucks");
merchantData.put("modeOfPayments", Arrays.asList("ECOM"));
merchantData.put("currency", "PHP");
merchantData.put("tin", "455691852");
merchantData.put("industry", "Food and Beverage");
merchantData.put("serviceDescription", "Specialty coffee retailer");
merchantData.put("isBrickAndMortarStore", true);
// Address
Map<String, Object> office = new HashMap<>();
office.put("city", "Portland");
office.put("line1", "111 Clarence Basler Rd");
office.put("buildingNameAndNumber", "Gresham Hub");
office.put("state", "Oregon(OR)");
office.put("postalCode", "97030");
office.put("contactNumber", "639865748123");
office.put("barangay", "Wilmington II");
Map<String, Object> address = new HashMap<>();
address.put("office", office);
merchantData.put("address", address);
// Websites
Map<String, Object> websites = new HashMap<>();
websites.put("businessWebsiteUrl", "https://www.starbucks.com/");
websites.put("isBusinessWebsiteUnderDevelopment", false);
merchantData.put("websites", websites);
// Representatives
Map<String, Object> authorized = new HashMap<>();
authorized.put("firstName", "David");
authorized.put("middleName", "Reese");
authorized.put("lastName", "Haven");
authorized.put("emailAddress", "david@haven.com");
authorized.put("contactNumber", "09789364458");
authorized.put("dateOfBirth", "1988-02-12T16:00:00.000Z");
authorized.put("position", "Accountant");
Map<String, Object> representatives = new HashMap<>();
representatives.put("authorized", authorized);
merchantData.put("representatives", representatives);
// Banks
Map<String, Object> bank1 = new HashMap<>();
bank1.put("accountDepositType", "GCASH");
bank1.put("bankName", "GCASH");
bank1.put("accountName", "Starbucks Corporation");
bank1.put("accountNumber", "09260000000");
Map<String, Object> bank2 = new HashMap<>();
bank2.put("accountDepositType", "BANK");
bank2.put("accountType", "SAVINGS");
bank2.put("bankName", "ASIA_UNITED_BANK");
bank2.put("accountName", "Starbucks Corporation");
bank2.put("accountNumber", "4716542700323890");
bank2.put("currency", "PHP");
merchantData.put("banks", Arrays.asList(bank1, bank2));
// Send request
Gson gson = new Gson();
String json = gson.toJson(merchantData);
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(json, JSON);
Request request = new Request.Builder()
.url(API_URL)
.header("Authorization", "Bearer " + token)
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
String responseBody = response.body().string();
if (response.isSuccessful()) {
System.out.println(" Merchant onboarded successfully");
System.out.println("Response: " + responseBody);
} else {
System.out.println(" Onboarding failed: HTTP " + response.code());
System.out.println("Details: " + responseBody);
}
}
}
public static void main(String[] args) {
try {
onboardMerchant();
} catch (IOException e) {
System.err.println(" Error: " + e.getMessage());
e.printStackTrace();
}
}
}
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
"github.com/golang-jwt/jwt/v5"
)
const apiURL = "https://kyc.sbx.moduluslabs.io/v2/onboard"
// generateToken creates a JWT token
func generateToken(accountID int, email, secretKey string) (string, error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"sub": accountID,
"email": email,
})
return token.SignedString([]byte(secretKey))
}
// onboardMerchant sends the onboarding request
func onboardMerchant() error {
secretKey := os.Getenv("MODULUS_ONBOARDING_SECRET_KEY")
if secretKey == "" {
return fmt.Errorf("MODULUS_ONBOARDING_SECRET_KEY environment variable not set")
}
token, err := generateToken(1, "merchant@gmail.com", secretKey)
if err != nil {
return fmt.Errorf("failed to generate token: %w", err)
}
merchantData := map[string]interface{}{
"businessType": "STARTER",
"legalName": "Starbucks",
"merchantName": "Starbucks",
"modeOfPayments": []string{"ECOM"},
"currency": "PHP",
"tin": "455691852",
"industry": "Food and Beverage",
"serviceDescription": "Specialty coffee retailer",
"isBrickAndMortarStore": true,
"address": map[string]interface{}{
"office": map[string]interface{}{
"city": "Portland",
"line1": "111 Clarence Basler Rd",
"buildingNameAndNumber": "Gresham Hub",
"state": "Oregon(OR)",
"postalCode": "97030",
"contactNumber": "639865748123",
"barangay": "Wilmington II",
},
},
"websites": map[string]interface{}{
"businessWebsiteUrl": "https://www.starbucks.com/",
"isBusinessWebsiteUnderDevelopment": false,
},
"representatives": map[string]interface{}{
"authorized": map[string]interface{}{
"firstName": "David",
"middleName": "Reese",
"lastName": "Haven",
"emailAddress": "david@haven.com",
"contactNumber": "09789364458",
"dateOfBirth": "1988-02-12T16:00:00.000Z",
"position": "Accountant",
},
},
"banks": []map[string]interface{}{
{
"accountDepositType": "GCASH",
"bankName": "GCASH",
"accountName": "Starbucks Corporation",
"accountNumber": "09260000000",
},
{
"accountDepositType": "BANK",
"accountType": "SAVINGS",
"bankName": "ASIA_UNITED_BANK",
"accountName": "Starbucks Corporation",
"accountNumber": "4716542700323890",
"currency": "PHP",
},
},
}
jsonData, err := json.Marshal(merchantData)
if err != nil {
return fmt.Errorf("failed to marshal data: %w", err)
}
req, err := http.NewRequest("POST", apiURL, bytes.NewBuffer(jsonData))
if err != nil {
return fmt.Errorf("failed to create request: %w", err)
}
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
resp, err := client.Do(req)
if err != nil {
return fmt.Errorf("request failed: %w", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("failed to read response: %w", err)
}
if resp.StatusCode == http.StatusOK {
var result map[string]interface{}
if err := json.Unmarshal(body, &result); err != nil {
return fmt.Errorf("failed to parse response: %w", err)
}
fmt.Println(" Merchant onboarded successfully")
fmt.Printf("Reference Number: %s\n", result["referenceNumber"])
return nil
}
fmt.Printf(" Onboarding failed: HTTP %d\n", resp.StatusCode)
fmt.Printf("Details: %s\n", string(body))
return fmt.Errorf("onboarding failed with status %d", resp.StatusCode)
}
func main() {
if err := onboardMerchant(); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
}
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.IdentityModel.Tokens.Jwt; // Install-Package System.IdentityModel.Tokens.Jwt
using Microsoft.IdentityModel.Tokens;
class Program
{
static async Task Main(string[] args)
{
await OnboardMerchant();
}
static string GenerateToken(int accountId, string email, string secretKey)
{
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.UTF8.GetBytes(secretKey);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new System.Security.Claims.ClaimsIdentity(new[]
{
new System.Security.Claims.Claim("sub", accountId.ToString()),
new System.Security.Claims.Claim("email", email)
}),
SigningCredentials = new SigningCredentials(
new SymmetricSecurityKey(key),
SecurityAlgorithms.HmacSha256Signature
)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
static async Task OnboardMerchant()
{
// Get secret key from environment variable
var secretKey = Environment.GetEnvironmentVariable("MODULUS_ONBOARDING_SECRET_KEY");
if (string.IsNullOrEmpty(secretKey))
{
Console.WriteLine(" Error: MODULUS_ONBOARDING_SECRET_KEY environment variable not set");
return;
}
// Generate JWT token
var token = GenerateToken(1, "merchant@gmail.com", secretKey);
try
{
// Create HTTP client with Bearer token authentication
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", token);
// Prepare merchant data
var merchantData = new
{
businessType = "STARTER",
legalName = "Starbucks",
merchantName = "Starbucks",
modeOfPayments = new[] { "ECOM" },
currency = "PHP",
tin = "455691852",
industry = "Food and Beverage",
serviceDescription = "Specialty coffee retailer",
isBrickAndMortarStore = true,
address = new
{
office = new
{
city = "Portland",
line1 = "111 Clarence Basler Rd",
buildingNameAndNumber = "Gresham Hub",
state = "Oregon(OR)",
postalCode = "97030",
contactNumber = "639865748123",
barangay = "Wilmington II"
}
},
websites = new
{
businessWebsiteUrl = "https://www.starbucks.com/",
isBusinessWebsiteUnderDevelopment = false
},
representatives = new
{
authorized = new
{
firstName = "David",
middleName = "Reese",
lastName = "Haven",
emailAddress = "david@haven.com",
contactNumber = "09789364458",
dateOfBirth = "1988-02-12T16:00:00.000Z",
position = "Accountant"
}
},
banks = new[]
{
new
{
accountDepositType = "GCASH",
bankName = "GCASH",
accountName = "Starbucks Corporation",
accountNumber = "09260000000"
},
new
{
accountDepositType = "BANK",
accountType = "SAVINGS",
bankName = "ASIA_UNITED_BANK",
accountName = "Starbucks Corporation",
accountNumber = "4716542700323890",
currency = "PHP"
}
}
};
var content = new StringContent(
JsonSerializer.Serialize(merchantData),
Encoding.UTF8,
"application/json"
);
// Send POST request
var response = await client.PostAsync(
"https://kyc.sbx.moduluslabs.io/v2/onboard",
content
);
var responseBody = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
var result = JsonSerializer.Deserialize<OnboardResponse>(
responseBody,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true }
);
Console.WriteLine(" Merchant onboarded successfully");
Console.WriteLine($"Reference Number: {result.ReferenceNumber}");
}
else
{
Console.WriteLine($" Onboarding failed: HTTP {(int)response.StatusCode}");
Console.WriteLine($"Details: {responseBody}");
}
}
catch (HttpRequestException e)
{
Console.WriteLine($" Request failed: {e.Message}");
}
catch (Exception e)
{
Console.WriteLine($" Error: {e.Message}");
}
}
}
// Response model
public class OnboardResponse
{
public string ReferenceNumber { get; set; }
}
{
"referenceNumber": "0a17c362-fe5c-4889-9cb5-47df71dac425"
}
{
"code": "20000004",
"error": "Please upload idsOfValidSignatories file/s before accessing this API.",
"referenceNumber": "02383ca9-8d72-47e2-9dcb-23e535a96122"
}
{
"code": "20000001",
"error": "Invalid or expired JWT token",
"referenceNumber": "097bf60a-bdab-40bf-b615-3c0eae693b86"
}
{
"code": "10000001",
"error": "An unexpected error occurred. Please try again later.",
"referenceNumber": "097bf60a-bdab-40bf-b615-3c0eae693b86"
}
Overview
This endpoint onboards a merchant to accept various payment methods. Before calling this API, you must upload all required documents using the File Upload API based on the business type.Prerequisites
Create Account
Upload Documents
Generate JWT Token
Submit Onboarding
Authentication
This endpoint requires JWT Bearer Token authentication. See the Authentication Guide for details.Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Request Parameters
Core Business Information
STARTER, SOLE_PROPRIETOR, PARTNERSHIP, CORPORATIONSee Business Type Enum for details.Example: "STARTER"businessType is SOLE_PROPRIETOR, PARTNERSHIP, or CORPORATIONNot required for: STARTER business typeExample: "Starbucks Corporation""Starbucks"TERMINAL, ECOM, PAYMENT_LINK, QRPH, PAY_WITH_MAYAExample: ["ECOM", "QRPH"]See Mode of Payment Enum for descriptions.PHP, USDDefault: PHPExample: "PHP""455691852""Food and Beverage""Coffee shop specializing in specialty beverages and light meals"trueIncorporators
STARTER: Not required (don’t include this field)SOLE_PROPRIETOR: Exactly 1 incorporator requiredPARTNERSHIP: Exactly 2 incorporators requiredCORPORATION: Minimum 3 incorporators required
Show Incorporator Object Properties
Show Incorporator Object Properties
"1988-02-12T16:00:00.000Z")Show Address Properties
Show Address Properties
Signatories
Address
Show Office Address (Required)
Show Office Address (Required)
Show Registered Address (Conditional)
Show Registered Address (Conditional)
SOLE_PROPRIETOR, PARTNERSHIP, CORPORATIONNot required for: STARTERWebsites
Representatives
Show Authorized Representative (Required)
Show Authorized Representative (Required)
Bank Accounts
Show Bank Account Properties
Show Bank Account Properties
SAVINGS, CHECKING_CURRENTRequired when: accountDepositType is BANKaccountDepositType is BANK, GCASH, or PAYMAYASee Bank Names Enum for valid valuesaccountDepositType is BANK, GCASH, or PAYMAYAaccountDepositType is BANK, GCASH, or PAYMAYAaccountDepositType is BANK, GCASH, or PAYMAYAValues: PHP, USDResponse
Success Response
Status Code:200 OK
"0a17c362-fe5c-4889-9cb5-47df71dac425"{
"referenceNumber": "0a17c362-fe5c-4889-9cb5-47df71dac425"
}
{
"referenceNumber": "0a17c362-fe5c-4889-9cb5-47df71dac425"
}
{
"code": "20000004",
"error": "Please upload idsOfValidSignatories file/s before accessing this API.",
"referenceNumber": "02383ca9-8d72-47e2-9dcb-23e535a96122"
}
{
"code": "20000001",
"error": "Invalid or expired JWT token",
"referenceNumber": "097bf60a-bdab-40bf-b615-3c0eae693b86"
}
{
"code": "10000001",
"error": "An unexpected error occurred. Please try again later.",
"referenceNumber": "097bf60a-bdab-40bf-b615-3c0eae693b86"
}
Error Responses
See Error Handling for complete error code reference.400 Bad Request - Missing Documents
400 Bad Request - Missing Documents
{
"code": "20000004",
"error": "Please upload idsOfValidSignatories file/s before accessing this API.",
"referenceNumber": "02383ca9-8d72-47e2-9dcb-23e535a96122"
}
400 Bad Request - Validation Error
400 Bad Request - Validation Error
{
"code": "20000005",
"error": "Invalid incorporator count for CORPORATION business type. Minimum 3 required.",
"referenceNumber": "abc123-def456-ghi789"
}
401 Unauthorized
401 Unauthorized
{
"code": "20000001",
"error": "Invalid or expired JWT token",
"referenceNumber": "xyz789-abc123-def456"
}
# First, generate JWT token (use script or online tool)
TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
curl -X POST https://kyc.sbx.moduluslabs.io/v2/onboard \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"businessType": "STARTER",
"merchantName": "Starbucks",
"modeOfPayments": ["ECOM"],
"currency": "PHP",
"tin": "455691852",
"industry": "Food and Beverage",
"serviceDescription": "Specialty coffee retailer",
"isBrickAndMortarStore": true,
"address": {
"office": {
"city": "Portland",
"line1": "111 Clarence Basler Rd",
"state": "Oregon(OR)",
"postalCode": "97030",
"contactNumber": "639865748123",
"barangay": "Wilmington II"
}
},
"representatives": {
"authorized": {
"firstName": "David",
"lastName": "Haven",
"emailAddress": "david@haven.com",
"contactNumber": "09789364458",
"dateOfBirth": "1988-02-12T16:00:00.000Z",
"position": "Accountant"
}
},
"banks": [
{
"accountDepositType": "GCASH",
"bankName": "GCASH",
"accountName": "Starbucks Corporation",
"accountNumber": "09260000000"
}
]
}'
const axios = require('axios');
const jwt = require('jsonwebtoken');
const SECRET_KEY = process.env.MODULUS_ONBOARDING_SECRET_KEY;
// Generate JWT token
function generateToken(accountId, email) {
return jwt.sign({ sub: accountId, email }, SECRET_KEY, { algorithm: 'HS256' });
}
// Onboard merchant
async function onboardMerchant() {
const token = generateToken(1, 'merchant@gmail.com');
const merchantData = {
businessType: 'STARTER',
legalName: 'Starbucks',
merchantName: 'Starbucks',
modeOfPayments: ['ECOM'],
currency: 'PHP',
tin: '455691852',
industry: 'Food and Beverage',
serviceDescription: 'Specialty coffee retailer',
isBrickAndMortarStore: true,
address: {
office: {
city: 'Portland',
line1: '111 Clarence Basler Rd',
buildingNameAndNumber: 'Gresham Hub',
state: 'Oregon(OR)',
postalCode: '97030',
contactNumber: '639865748123',
barangay: 'Wilmington II'
}
},
websites: {
businessWebsiteUrl: 'https://www.starbucks.com/',
isBusinessWebsiteUnderDevelopment: false
},
representatives: {
authorized: {
firstName: 'David',
middleName: 'Reese',
lastName: 'Haven',
emailAddress: 'david@haven.com',
contactNumber: '09789364458',
dateOfBirth: '1988-02-12T16:00:00.000Z',
position: 'Accountant'
}
},
banks: [
{
accountDepositType: 'GCASH',
bankName: 'GCASH',
accountName: 'Starbucks Corporation',
accountNumber: '09260000000'
},
{
accountDepositType: 'BANK',
accountType: 'SAVINGS',
bankName: 'ASIA_UNITED_BANK',
accountName: 'Starbucks Corporation',
accountNumber: '4716542700323890',
currency: 'PHP'
}
]
};
try {
const response = await axios.post(
'https://kyc.sbx.moduluslabs.io/v2/onboard',
merchantData,
{
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
}
);
console.log(' Merchant onboarded successfully');
console.log('Reference Number:', response.data.referenceNumber);
return response.data;
} catch (error) {
console.error(' Onboarding failed:', error.response?.data || error.message);
throw error;
}
}
onboardMerchant();
import os
import requests
import jwt
SECRET_KEY = os.getenv('MODULUS_ONBOARDING_SECRET_KEY')
def generate_token(account_id, email):
"""Generate JWT token"""
return jwt.encode(
{'sub': account_id, 'email': email},
SECRET_KEY,
algorithm='HS256'
)
def onboard_merchant():
"""Onboard a merchant"""
token = generate_token(1, 'merchant@gmail.com')
merchant_data = {
'businessType': 'STARTER',
'legalName': 'Starbucks',
'merchantName': 'Starbucks',
'modeOfPayments': ['ECOM'],
'currency': 'PHP',
'tin': '455691852',
'industry': 'Food and Beverage',
'serviceDescription': 'Specialty coffee retailer',
'isBrickAndMortarStore': True,
'address': {
'office': {
'city': 'Portland',
'line1': '111 Clarence Basler Rd',
'buildingNameAndNumber': 'Gresham Hub',
'state': 'Oregon(OR)',
'postalCode': '97030',
'contactNumber': '639865748123',
'barangay': 'Wilmington II'
}
},
'representatives': {
'authorized': {
'firstName': 'David',
'middleName': 'Reese',
'lastName': 'Haven',
'emailAddress': 'david@haven.com',
'contactNumber': '09789364458',
'dateOfBirth': '1988-02-12T16:00:00.000Z',
'position': 'Accountant'
}
},
'banks': [
{
'accountDepositType': 'GCASH',
'bankName': 'GCASH',
'accountName': 'Starbucks Corporation',
'accountNumber': '09260000000'
}
]
}
try:
response = requests.post(
'https://kyc.sbx.moduluslabs.io/v2/onboard',
json=merchant_data,
headers={
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
)
response.raise_for_status()
print(' Merchant onboarded successfully')
print(f"Reference Number: {response.json()['referenceNumber']}")
return response.json()
except requests.exceptions.HTTPError as e:
print(f' Onboarding failed: {e.response.text}')
raise
if __name__ == '__main__':
onboard_merchant()
<?php
require 'vendor/autoload.php'; // composer require firebase/php-jwt guzzlehttp/guzzle
use Firebase\JWT\JWT;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
$secretKey = getenv('MODULUS_ONBOARDING_SECRET_KEY');
/**
* Generate JWT token
*/
function generateToken($accountId, $email, $secretKey) {
$payload = [
'sub' => $accountId,
'email' => $email
];
return JWT::encode($payload, $secretKey, 'HS256');
}
/**
* Onboard a merchant
*/
function onboardMerchant() {
global $secretKey;
$token = generateToken(1, 'merchant@gmail.com', $secretKey);
$merchantData = [
'businessType' => 'STARTER',
'legalName' => 'Starbucks',
'merchantName' => 'Starbucks',
'modeOfPayments' => ['ECOM'],
'currency' => 'PHP',
'tin' => '455691852',
'industry' => 'Food and Beverage',
'serviceDescription' => 'Specialty coffee retailer',
'isBrickAndMortarStore' => true,
'address' => [
'office' => [
'city' => 'Portland',
'line1' => '111 Clarence Basler Rd',
'buildingNameAndNumber' => 'Gresham Hub',
'state' => 'Oregon(OR)',
'postalCode' => '97030',
'contactNumber' => '639865748123',
'barangay' => 'Wilmington II'
]
],
'websites' => [
'businessWebsiteUrl' => 'https://www.starbucks.com/',
'isBusinessWebsiteUnderDevelopment' => false
],
'representatives' => [
'authorized' => [
'firstName' => 'David',
'middleName' => 'Reese',
'lastName' => 'Haven',
'emailAddress' => 'david@haven.com',
'contactNumber' => '09789364458',
'dateOfBirth' => '1988-02-12T16:00:00.000Z',
'position' => 'Accountant'
]
],
'banks' => [
[
'accountDepositType' => 'GCASH',
'bankName' => 'GCASH',
'accountName' => 'Starbucks Corporation',
'accountNumber' => '09260000000'
],
[
'accountDepositType' => 'BANK',
'accountType' => 'SAVINGS',
'bankName' => 'ASIA_UNITED_BANK',
'accountName' => 'Starbucks Corporation',
'accountNumber' => '4716542700323890',
'currency' => 'PHP'
]
]
];
try {
$client = new Client();
$response = $client->post('https://kyc.sbx.moduluslabs.io/v2/onboard', [
'headers' => [
'Authorization' => 'Bearer ' . $token,
'Content-Type' => 'application/json'
],
'json' => $merchantData
]);
$body = json_decode($response->getBody(), true);
echo " Merchant onboarded successfully\n";
echo "Reference Number: " . $body['referenceNumber'] . "\n";
return $body;
} catch (RequestException $e) {
echo " Onboarding failed: " . $e->getMessage() . "\n";
if ($e->hasResponse()) {
echo $e->getResponse()->getBody() . "\n";
}
throw $e;
}
}
onboardMerchant();
?>
import com.google.gson.Gson;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import okhttp3.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.security.Key;
import java.util.*;
public class OnboardMerchant {
private static final String SECRET_KEY = System.getenv("MODULUS_ONBOARDING_SECRET_KEY");
private static final String API_URL = "https://kyc.sbx.moduluslabs.io/v2/onboard";
private static final MediaType JSON = MediaType.get("application/json; charset=utf-8");
/**
* Generate JWT token
*/
public static String generateToken(int accountId, String email) {
Key key = new SecretKeySpec(SECRET_KEY.getBytes(), SignatureAlgorithm.HS256.getJcaName());
return Jwts.builder()
.claim("sub", accountId)
.claim("email", email)
.signWith(key, SignatureAlgorithm.HS256)
.compact();
}
/**
* Onboard a merchant
*/
public static void onboardMerchant() throws IOException {
String token = generateToken(1, "merchant@gmail.com");
// Create merchant data
Map<String, Object> merchantData = new HashMap<>();
merchantData.put("businessType", "STARTER");
merchantData.put("legalName", "Starbucks");
merchantData.put("merchantName", "Starbucks");
merchantData.put("modeOfPayments", Arrays.asList("ECOM"));
merchantData.put("currency", "PHP");
merchantData.put("tin", "455691852");
merchantData.put("industry", "Food and Beverage");
merchantData.put("serviceDescription", "Specialty coffee retailer");
merchantData.put("isBrickAndMortarStore", true);
// Address
Map<String, Object> office = new HashMap<>();
office.put("city", "Portland");
office.put("line1", "111 Clarence Basler Rd");
office.put("buildingNameAndNumber", "Gresham Hub");
office.put("state", "Oregon(OR)");
office.put("postalCode", "97030");
office.put("contactNumber", "639865748123");
office.put("barangay", "Wilmington II");
Map<String, Object> address = new HashMap<>();
address.put("office", office);
merchantData.put("address", address);
// Websites
Map<String, Object> websites = new HashMap<>();
websites.put("businessWebsiteUrl", "https://www.starbucks.com/");
websites.put("isBusinessWebsiteUnderDevelopment", false);
merchantData.put("websites", websites);
// Representatives
Map<String, Object> authorized = new HashMap<>();
authorized.put("firstName", "David");
authorized.put("middleName", "Reese");
authorized.put("lastName", "Haven");
authorized.put("emailAddress", "david@haven.com");
authorized.put("contactNumber", "09789364458");
authorized.put("dateOfBirth", "1988-02-12T16:00:00.000Z");
authorized.put("position", "Accountant");
Map<String, Object> representatives = new HashMap<>();
representatives.put("authorized", authorized);
merchantData.put("representatives", representatives);
// Banks
Map<String, Object> bank1 = new HashMap<>();
bank1.put("accountDepositType", "GCASH");
bank1.put("bankName", "GCASH");
bank1.put("accountName", "Starbucks Corporation");
bank1.put("accountNumber", "09260000000");
Map<String, Object> bank2 = new HashMap<>();
bank2.put("accountDepositType", "BANK");
bank2.put("accountType", "SAVINGS");
bank2.put("bankName", "ASIA_UNITED_BANK");
bank2.put("accountName", "Starbucks Corporation");
bank2.put("accountNumber", "4716542700323890");
bank2.put("currency", "PHP");
merchantData.put("banks", Arrays.asList(bank1, bank2));
// Send request
Gson gson = new Gson();
String json = gson.toJson(merchantData);
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(json, JSON);
Request request = new Request.Builder()
.url(API_URL)
.header("Authorization", "Bearer " + token)
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
String responseBody = response.body().string();
if (response.isSuccessful()) {
System.out.println(" Merchant onboarded successfully");
System.out.println("Response: " + responseBody);
} else {
System.out.println(" Onboarding failed: HTTP " + response.code());
System.out.println("Details: " + responseBody);
}
}
}
public static void main(String[] args) {
try {
onboardMerchant();
} catch (IOException e) {
System.err.println(" Error: " + e.getMessage());
e.printStackTrace();
}
}
}
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
"github.com/golang-jwt/jwt/v5"
)
const apiURL = "https://kyc.sbx.moduluslabs.io/v2/onboard"
// generateToken creates a JWT token
func generateToken(accountID int, email, secretKey string) (string, error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"sub": accountID,
"email": email,
})
return token.SignedString([]byte(secretKey))
}
// onboardMerchant sends the onboarding request
func onboardMerchant() error {
secretKey := os.Getenv("MODULUS_ONBOARDING_SECRET_KEY")
if secretKey == "" {
return fmt.Errorf("MODULUS_ONBOARDING_SECRET_KEY environment variable not set")
}
token, err := generateToken(1, "merchant@gmail.com", secretKey)
if err != nil {
return fmt.Errorf("failed to generate token: %w", err)
}
merchantData := map[string]interface{}{
"businessType": "STARTER",
"legalName": "Starbucks",
"merchantName": "Starbucks",
"modeOfPayments": []string{"ECOM"},
"currency": "PHP",
"tin": "455691852",
"industry": "Food and Beverage",
"serviceDescription": "Specialty coffee retailer",
"isBrickAndMortarStore": true,
"address": map[string]interface{}{
"office": map[string]interface{}{
"city": "Portland",
"line1": "111 Clarence Basler Rd",
"buildingNameAndNumber": "Gresham Hub",
"state": "Oregon(OR)",
"postalCode": "97030",
"contactNumber": "639865748123",
"barangay": "Wilmington II",
},
},
"websites": map[string]interface{}{
"businessWebsiteUrl": "https://www.starbucks.com/",
"isBusinessWebsiteUnderDevelopment": false,
},
"representatives": map[string]interface{}{
"authorized": map[string]interface{}{
"firstName": "David",
"middleName": "Reese",
"lastName": "Haven",
"emailAddress": "david@haven.com",
"contactNumber": "09789364458",
"dateOfBirth": "1988-02-12T16:00:00.000Z",
"position": "Accountant",
},
},
"banks": []map[string]interface{}{
{
"accountDepositType": "GCASH",
"bankName": "GCASH",
"accountName": "Starbucks Corporation",
"accountNumber": "09260000000",
},
{
"accountDepositType": "BANK",
"accountType": "SAVINGS",
"bankName": "ASIA_UNITED_BANK",
"accountName": "Starbucks Corporation",
"accountNumber": "4716542700323890",
"currency": "PHP",
},
},
}
jsonData, err := json.Marshal(merchantData)
if err != nil {
return fmt.Errorf("failed to marshal data: %w", err)
}
req, err := http.NewRequest("POST", apiURL, bytes.NewBuffer(jsonData))
if err != nil {
return fmt.Errorf("failed to create request: %w", err)
}
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
resp, err := client.Do(req)
if err != nil {
return fmt.Errorf("request failed: %w", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("failed to read response: %w", err)
}
if resp.StatusCode == http.StatusOK {
var result map[string]interface{}
if err := json.Unmarshal(body, &result); err != nil {
return fmt.Errorf("failed to parse response: %w", err)
}
fmt.Println(" Merchant onboarded successfully")
fmt.Printf("Reference Number: %s\n", result["referenceNumber"])
return nil
}
fmt.Printf(" Onboarding failed: HTTP %d\n", resp.StatusCode)
fmt.Printf("Details: %s\n", string(body))
return fmt.Errorf("onboarding failed with status %d", resp.StatusCode)
}
func main() {
if err := onboardMerchant(); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
}
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.IdentityModel.Tokens.Jwt; // Install-Package System.IdentityModel.Tokens.Jwt
using Microsoft.IdentityModel.Tokens;
class Program
{
static async Task Main(string[] args)
{
await OnboardMerchant();
}
static string GenerateToken(int accountId, string email, string secretKey)
{
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.UTF8.GetBytes(secretKey);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new System.Security.Claims.ClaimsIdentity(new[]
{
new System.Security.Claims.Claim("sub", accountId.ToString()),
new System.Security.Claims.Claim("email", email)
}),
SigningCredentials = new SigningCredentials(
new SymmetricSecurityKey(key),
SecurityAlgorithms.HmacSha256Signature
)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
static async Task OnboardMerchant()
{
// Get secret key from environment variable
var secretKey = Environment.GetEnvironmentVariable("MODULUS_ONBOARDING_SECRET_KEY");
if (string.IsNullOrEmpty(secretKey))
{
Console.WriteLine(" Error: MODULUS_ONBOARDING_SECRET_KEY environment variable not set");
return;
}
// Generate JWT token
var token = GenerateToken(1, "merchant@gmail.com", secretKey);
try
{
// Create HTTP client with Bearer token authentication
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", token);
// Prepare merchant data
var merchantData = new
{
businessType = "STARTER",
legalName = "Starbucks",
merchantName = "Starbucks",
modeOfPayments = new[] { "ECOM" },
currency = "PHP",
tin = "455691852",
industry = "Food and Beverage",
serviceDescription = "Specialty coffee retailer",
isBrickAndMortarStore = true,
address = new
{
office = new
{
city = "Portland",
line1 = "111 Clarence Basler Rd",
buildingNameAndNumber = "Gresham Hub",
state = "Oregon(OR)",
postalCode = "97030",
contactNumber = "639865748123",
barangay = "Wilmington II"
}
},
websites = new
{
businessWebsiteUrl = "https://www.starbucks.com/",
isBusinessWebsiteUnderDevelopment = false
},
representatives = new
{
authorized = new
{
firstName = "David",
middleName = "Reese",
lastName = "Haven",
emailAddress = "david@haven.com",
contactNumber = "09789364458",
dateOfBirth = "1988-02-12T16:00:00.000Z",
position = "Accountant"
}
},
banks = new[]
{
new
{
accountDepositType = "GCASH",
bankName = "GCASH",
accountName = "Starbucks Corporation",
accountNumber = "09260000000"
},
new
{
accountDepositType = "BANK",
accountType = "SAVINGS",
bankName = "ASIA_UNITED_BANK",
accountName = "Starbucks Corporation",
accountNumber = "4716542700323890",
currency = "PHP"
}
}
};
var content = new StringContent(
JsonSerializer.Serialize(merchantData),
Encoding.UTF8,
"application/json"
);
// Send POST request
var response = await client.PostAsync(
"https://kyc.sbx.moduluslabs.io/v2/onboard",
content
);
var responseBody = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
var result = JsonSerializer.Deserialize<OnboardResponse>(
responseBody,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true }
);
Console.WriteLine(" Merchant onboarded successfully");
Console.WriteLine($"Reference Number: {result.ReferenceNumber}");
}
else
{
Console.WriteLine($" Onboarding failed: HTTP {(int)response.StatusCode}");
Console.WriteLine($"Details: {responseBody}");
}
}
catch (HttpRequestException e)
{
Console.WriteLine($" Request failed: {e.Message}");
}
catch (Exception e)
{
Console.WriteLine($" Error: {e.Message}");
}
}
}
// Response model
public class OnboardResponse
{
public string ReferenceNumber { get; set; }
}
Business Type Examples
- Starter Business
- Sole Proprietor
- Partnership
- Corporation
{
"businessType": "STARTER",
"merchantName": "My Coffee Shop",
"modeOfPayments": ["ECOM", "QRPH"],
"currency": "PHP",
"tin": "123456789",
"industry": "Food and Beverage",
"serviceDescription": "Local coffee shop",
"isBrickAndMortarStore": true,
"address": {
"office": { /* required */ }
},
"representatives": {
"authorized": { /* required */ }
},
"banks": [ /* at least one required */ ]
}
legalName, incorporators, or registered address.{
"businessType": "SOLE_PROPRIETOR",
"legalName": "Juan Dela Cruz Trading",
"merchantName": "JDC Store",
"incorporators": [
{
"firstName": "Juan",
"lastName": "Dela Cruz",
"emailAddress": "juan@email.com",
"contactNumber": "09123456789",
"natureOfWork": "Retail",
"sourceOfFunds": "BUSINESS_INCOME",
"nationality": "Filipino",
"dateOfBirth": "1985-01-15T00:00:00.000Z",
"address": { /* required */ }
}
],
"address": {
"office": { /* required */ },
"registered": { /* required */ }
},
/* ... other required fields ... */
}
{
"businessType": "PARTNERSHIP",
"legalName": "Smith & Jones Partnership",
"merchantName": "S&J Enterprises",
"incorporators": [
{
"firstName": "John",
"lastName": "Smith",
/* ... complete details ... */
},
{
"firstName": "Mary",
"lastName": "Jones",
/* ... complete details ... */
}
],
"address": {
"office": { /* required */ },
"registered": { /* required */ }
},
/* ... other required fields ... */
}
{
"businessType": "CORPORATION",
"legalName": "Acme Corporation Inc.",
"merchantName": "Acme Corp",
"incorporators": [
{ /* incorporator 1 - complete details */ },
{ /* incorporator 2 - complete details */ },
{ /* incorporator 3 - complete details */ }
],
"signatories": [
{
"firstName": "Jane",
"lastName": "Doe",
"position": "CEO"
}
],
"address": {
"office": { /* required */ },
"registered": { /* required */ }
},
/* ... other required fields ... */
}
Best Practices
Upload Documents First
Validate Before Submit
Use Correct Business Type
Test with Sandbox
Store Reference Number
Handle Errors Gracefully
Validation Checklist
Before submitting:Business Type
Incorporators
Addresses
Bank Accounts
Documents
Next Steps
Store Reference Number
Enums Reference
Error Handling
Authentication
Authorizations
JWT Bearer token authentication
Body
Trading name or DBA (Doing Business As) name
500List of accepted payment modes
1CREDIT_CARD, DEBIT_CARD, GCASH, GRABPAY, PAYMAYA, BANK_TRANSFER Primary currency for transactions
PHP, USD Tax Identification Number
20^\d+$Business industry category
200Description of services or products offered
Whether the business has a physical store location
Show child attributes
Show child attributes
Show child attributes
Show child attributes
List of bank accounts for settlement
1 - 2 elementsShow child attributes
Show child attributes
Legal registered name of the business (required for non-STARTER types)
500Unique business handle/slug for payment links (required for non-STARTER types)
^([A-Za-z]|[0-9]|_|-)+$List of business incorporators (for non-STARTER types)
1 - 5 elementsShow child attributes
Show child attributes
List of authorized signatories
1 - 5 elementsShow child attributes
Show child attributes
Show child attributes
Show child attributes
Was this page helpful?