Jamm API Python SDK
Project description
Jamm SDK for Python
Lightweight Python client for the Jamm API. Focused on:
- Straightforward auth (client credentials OAuth2)
- Clean dict responses (flattened where practical)
- Helpful error metadata (
error_type,error_code, decoded debug values) - Simple pagination (lazy charge iterator)
Installation
Production (when published):
pip install jamm-sdk
Local development (editable):
pip install -e .
Quick Start
import jamm
client = jamm.configure(
client_id="your_client_id",
client_secret="your_client_secret",
env="develop", # or "staging" / "production"
)
print(client.healthcheck())
Configuration
The SDK can be configured using environment variables or programmatically:
Programmatic Configuration
from jamm import JammClient, ClientConfig
config = ClientConfig(
api_base_url="https://api.staging.jamm.com/v1",
client_id="your_client_id",
client_secret="your_client_secret"
)
client = JammClient(config)
Features Overview
| Domain | Highlights |
|---|---|
| Healthcheck | Ping connectivity quickly |
| Customers | CRUD + contract; normalized: link_initialized, bank_information, status |
| Payments | On-session / off-session flows |
| Contracts | Fetch existing customer contract |
| Charges | Get, list, lazy iterator charges.iter() |
| Banking | Bank search, major banks, branches (get/search/list) |
| Errors | Unified ApiError with rich metadata |
API Reference
Health Check
# Verify API connectivity
response = client.healthcheck()
print(response)
Customer Management
buyer_data = {
"email": "customer@example.com",
"name": "John Doe",
"katakana_last_name": "ドウ",
"katakana_first_name": "ジョン",
"address": "123 Tokyo Street, Shibuya",
"birth_date": "1990-01-01",
"gender": "male",
"force_kyc": False,
"metadata": {"source": "api"}
}
customer = client.customers.create(buyer=buyer_data)
print(customer["id"]) # flattened
customer = client.customers.get("cus-customer_id_here")
updated = client.customers.update(
customer_id="cus-customer_id_here",
data={"name": "Updated Name", "metadata": {"updated": True}},
)
contract = client.customers.get_contract("cus-customer_id_here")
delete_result = client.customers.delete("cus-customer_id_here")
Payment Processing
from datetime import datetime, timedelta
expires_at = (datetime.now() + timedelta(days=2)).isoformat() + "Z"
off_session = client.payments.off_session(
customer_id="cus-customer_id_here",
price=1000,
description="Monthly subscription",
expires_at=expires_at,
)
on_session = client.payments.on_session(
customer_id="cus-customer_id_here",
price=1000,
description="One-time payment",
redirect_urls={
"success_url": "https://yoursite.com/success",
"failure_url": "https://yoursite.com/cancel",
},
expires_at=expires_at,
)
new_customer_session = client.payments.on_session(
buyer=buyer_data,
redirect_urls={
"success_url": "https://yoursite.com/success",
"failure_url": "https://yoursite.com/cancel",
},
expires_at=expires_at,
)
new_customer_with_charge = client.payments.on_session(
buyer=buyer_data,
price=1000,
description="Initial payment",
redirect_urls={
"success_url": "https://yoursite.com/success",
"failure_url": "https://yoursite.com/cancel",
},
expires_at=expires_at,
)
Contract Management
contract = client.contracts.get("cus-customer_id_here")
if contract:
print("Contract found")
else:
print("No active contract")
Charge Operations
charge = client.charges.get("trx-charge_id_here")
page = client.charges.list(customer_id="cus-customer_id_here", page_size=25)
for c in client.charges.iter(customer_id="cus-customer_id_here", page_size=100, limit=500):
process(c)
Banking Operations
bank = client.banks.get("0001")
major_banks = client.banks.get_major_banks()
search_results = client.banks.search("みずほ")
branch = client.bank_branches.get("0001", "001")
branches = client.bank_branches.search("0001", "東京")
all_branches = client.bank_branches.list_for_bank("0001")
Authentication
OAuth2 client credentials handled automatically once configured.
Development Setup
python -m venv venv
source venv/bin/activate
pip install -e .
Running Tests
python tests/test_sdk.py --client-id YOUR_ID --client-secret YOUR_SECRET --env develop
Abbreviated example output:
✅ Healthcheck ok
✅ Customer created
✅ Off-session payment created
✅ On-session payment created
✅ Major banks fetched
Helper: generate_buyer()
from faker import Faker
import time
def generate_buyer(base_email=None, name=None, force_kyc=False):
"""Generate realistic buyer data for testing"""
fake_en = Faker("en_US")
fake_jp = Faker("ja_JP")
timestamp = int(time.time())
return {
"email": f"{fake_en.user_name()}+{timestamp}@jamm-pay.jp",
"name": name or fake_en.name(),
"katakana_last_name": fake_jp.last_kana_name(),
"katakana_first_name": fake_jp.first_kana_name(),
"address": fake_jp.address(),
"birth_date": fake_en.date_of_birth(minimum_age=20, maximum_age=70).strftime("%Y-%m-%d"),
"gender": fake_en.random_element(["male", "female"]),
"force_kyc": force_kyc,
"metadata": {"source": "faker_generated", "timestamp": str(timestamp)}
}
# Usage
buyer_data = generate_buyer()
customer = client.customers.create(buyer=buyer_data)
Error Handling
Every failed SDK call raises jamm.ApiError.
| Field | Meaning |
|---|---|
code |
HTTP status (0 = network/transport) |
message |
Short description |
details |
Parsed JSON body |
error_type |
Internal debug enum-like (e.g. ERROR_TYPE_PAYMENT_CHARGE_FAILED) |
error_code |
High-level code (internal, invalid, etc.) |
debug_values |
All collected debug markers |
decoded_values |
Base64-decoded detail values |
from jamm import ApiError
try:
client.charges.get("trx-nonexistent")
except ApiError as e:
print(e.code, e.message, e.error_type)
if e.error_code:
print("error_code:", e.error_code)
if e.decoded_values:
print("decoded:", e.decoded_values)
Network issues surface with code == 0 and details containing {"network_error": True}.
Notes & Next Steps
Planned (non-breaking): enum wrapper for error_type, helper predicates, optional typed response models. Contributions welcome.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file jamm-0.3.0.tar.gz.
File metadata
- Download URL: jamm-0.3.0.tar.gz
- Upload date:
- Size: 84.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
754fdd2356468c10f9253fd657f62a09ed453d4ee26f88d1ca7fd4085888f63a
|
|
| MD5 |
5f3f8ea1486b9d0eed0088f1a8f36708
|
|
| BLAKE2b-256 |
4f868276d184caed2053f6db322d9729fbc7f076f087e82c7b86f7cedd1a0b4a
|
File details
Details for the file jamm-0.3.0-py3-none-any.whl.
File metadata
- Download URL: jamm-0.3.0-py3-none-any.whl
- Upload date:
- Size: 38.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e6d6f946cbd389a9789c873c45825cc1918329db29ba2452d6dbcce61ad0e36b
|
|
| MD5 |
99b84fca234bc663e21a569834fee89e
|
|
| BLAKE2b-256 |
034f10dc0e822c0adbc08fb4ed63d3e8f86d1aa0168992f1f227a78468c64ace
|