-
Notifications
You must be signed in to change notification settings - Fork 0
Home
The SDK can now parse EVENT_TYPE_USER_ACCOUNT_DELETED webhooks, which are fired when a Jamm user account is deleted. Previously, these payloads raised Unknown event type.
message = Jamm::Webhook.parse(json_hash)
case message.event_type
when Jamm::OpenAPI::EventType::USER_ACCOUNT_DELETED 👈️👈️👈️
account = message.content
puts account.customer # "cus-..."
puts account.email
puts account.deleted_at
puts account.merchant_name
endRefund webhook payloads now surface the refund's rfd- identifier on both the flat refund_id attribute and the nested refund.id, so either path works:
when Jamm::OpenAPI::EventType::REFUND_SUCCEEDED
charge = message.content
puts charge.refund_id # "rfd-..." 👈️ flat attribute
puts charge.refund.id # "rfd-..." 👈️ nested attributeWebhook parsing no longer fails when the Jamm backend adds new fields to a payload. Unknown keys are silently dropped instead of raising ArgumentError, so SDK upgrades are no longer required to keep ingesting webhooks after a backend release.
The Jamm backend serializes webhooks with Go's json.Marshal (not protojson), so every enum field (status, api_source, ...) arrives on the wire as an integer. The SDK now maps every numeric enum back to its string constant on every webhook model, matching the values returned by the REST API:
when Jamm::OpenAPI::EventType::REFUND_SUCCEEDED
charge = message.content
charge.status # "STATUS_REFUNDED" (was: 5) 👈️👈️👈️
charge.api_source # "API_SOURCE_OFF_SESSION" (was: 2) 👈️👈️👈️Nested webhook fields (e.g. refund, refund.error) are now coerced into typed model instances instead of staying as raw Hash values. Typed accessors like error.code / error.message work as documented instead of raising NoMethodError:
when Jamm::OpenAPI::EventType::REFUND_FAILED
refund = message.content.refund # Jamm::OpenAPI::RefundInfo 👈️ typed
error = refund.error # Jamm::OpenAPI::ChargeError 👈️ typed
puts error.code # works (was: NoMethodError)
puts error.messageJamm::Webhook.parse now accepts payloads with either string keys (JSON.parse(body)) or symbol keys (JSON.parse(body, symbolize_names: true)). Both decode paths are normalized internally, so callers can pick whichever they prefer:
# Both work in 2.3.0
Jamm::Webhook.parse(JSON.parse(body))
Jamm::Webhook.parse(JSON.parse(body, symbolize_names: true))A new Jamm::Payment.off_session_async method has been added for async off-session charges. Unlike the synchronous off_session, the API returns immediately with a request_id and the final charge result is delivered later via webhook (CHARGE_SUCCESS / CHARGE_FAIL).
response = Jamm::Payment.off_session_async(
customer: 'cus-12345',
charge: Jamm::OpenAPI::InitialCharge.new(
price: 1000,
description: 'Test payment',
),
)
response.request_id # request identifier for tracking
response.status # Jamm::OpenAPI::AsyncStatus (e.g. "ASYNC_STATUS_PENDING")
response.charge_id # populated once the charge has been created
# Platform mode
Jamm::Payment.off_session_async(
merchant: 'mer-12345',
customer: 'cus-12345',
charge: charge,
)off_session_async auto-fills idempotency_key with a UUID when the caller passes nil or a blank string, so every async charge is retry-safe by default. A caller-supplied key is left untouched so explicit retries reuse the same value:
# Auto-generated UUID (default)
Jamm::Payment.off_session_async(customer: 'cus-12345', charge: charge)
# Caller-supplied key — preserved as-is for safe retries
Jamm::Payment.off_session_async(
customer: 'cus-12345',
charge: charge,
idempotency_key: 'order-2026-0042', 👈️👈️👈️
)Refund outcomes are now delivered via two separate webhook events, replacing the single CHARGE_REFUND event:
-
EVENT_TYPE_REFUND_SUCCEEDED— fired when a refund completes successfully -
EVENT_TYPE_REFUND_FAILED— fired when a refund fails
message = Jamm::Webhook.parse(json_hash)
case message.event_type
when Jamm::OpenAPI::EventType::REFUND_SUCCEEDED 👈️👈️👈️
refund = message.refund
puts refund.refund_id # "rfd-..."
puts refund.amount_refunded
puts refund.jamm_fee
puts refund.consumption_tax # 10% of Jamm fee
puts refund.original_transaction_fee_waived # true for same-day cancel
puts refund.processed_at
when Jamm::OpenAPI::EventType::REFUND_FAILED 👈️👈️👈️
error = message.refund&.error
puts error.code # Jamm error code
puts error.message # human-readable description
endRefund webhook payloads now include a nested refund object (Jamm::OpenAPI::RefundInfo) with detailed refund information:
| Field | Type | Description |
|---|---|---|
refund_id |
String | Refund identifier (rfd-* format) |
amount_refunded |
Integer | Refund amount |
jamm_fee |
Integer | Jamm fee charged for this refund |
consumption_tax |
Integer | 10% of Jamm fee |
original_transaction_fee_waived |
Boolean |
true for same-day cancellation |
error |
ChargeError | Error details (on failure only) |
processed_at |
String | Processing timestamp |
A new Jamm::OpenAPI::ChargeError model provides structured error details for failed refunds:
error = message.refund&.error
error.code # Jamm error code string
error.message # human-readable descriptionThe webhook ChargeMessage payload now includes additional fields for refund events:
| Field | Type | Description |
|---|---|---|
jamm_fee |
Integer | Jamm fee for this refund |
consumption_tax |
Integer | 10% of Jamm fee |
original_transaction_jamm_fee |
String |
"waived" or "not_waived"
|
refund_id |
String | External refund identifier (rfd-*) |
refund |
RefundInfo | Nested refund details object |
A new ChargeMessageStatus::REFUNDED (STATUS_REFUNDED) value has been added to indicate that a charge has been fully refunded.
The CHARGE_REFUND event type has been removed and replaced with two granular events. Update your webhook handler:
# BEFORE (2.0.0)
when Jamm::OpenAPI::EventType::CHARGE_REFUND
# AFTER (2.1.0)
when Jamm::OpenAPI::EventType::REFUND_SUCCEEDED 👈️👈️👈️
# handle successful refund
when Jamm::OpenAPI::EventType::REFUND_FAILED 👈️👈️👈️
# handle failed refundThe SDK now supports Platform Mode, allowing platformers to call the Jamm API on behalf of their merchants.
Configure platform mode during initialization:
Jamm.configure(
client_id: '<your client id>',
client_secret: '<your client secret>',
env: 'production',
platform: true, 👈️👈️👈️
)Once configured, all API methods accept an optional merchant: parameter to specify which merchant to act on behalf of:
# Payment on behalf of a merchant
Jamm::Payment.on_session(
merchant: 'mer-12345', 👈️👈️👈️
buyer: Jamm::OpenAPI::Buyer.new(
email: 'foo@example.com',
name: 'Yamada Taro',
),
charge: Jamm::OpenAPI::InitialCharge.new(
price: 1000,
description: 'Test payment',
),
redirect: Jamm::OpenAPI::URL.new(
success_url: 'https://jamm-pay.jp/success',
failure_url: 'https://jamm-pay.jp/fail',
)
)
# Customer management on behalf of a merchant
Jamm::Customer.get('cus-12345', merchant: 'mer-12345')
Jamm::Customer.create(buyer: buyer, merchant: 'mer-12345')
Jamm::Customer.update('cus-12345', params, merchant: 'mer-12345')
Jamm::Customer.delete('cus-12345', merchant: 'mer-12345')The merchant: parameter is available on all modules: Payment, Customer, Healthcheck.
A new Jamm::Payment.refund method is now available. If the same-day cancellation window has not passed, the charge is cancelled directly. Otherwise, a bank transfer refund request is created. The final result is delivered via webhook (charge_refund).
request = Jamm::OpenAPI::RefundRequest.new(
charge: 'chg-12345',
)
Jamm::Payment.refund(request)
# Platform mode
Jamm::Payment.refund(request, merchant: 'mer-12345')A new ChargeStatus enum has been added with the following values:
CHARGE_STATUS_SUCCESSCHARGE_STATUS_FAILURECHARGE_STATUS_WAITING_EKYCCHARGE_STATUS_BLOCKINGCHARGE_STATUS_CANCELLEDCHARGE_STATUS_REFUNDEDCHARGE_STATUS_PENDING
Jamm.configure now accepts an optional platform: keyword argument. Existing calls without platform: will continue to work (defaults to false), but the SDK now sets Jamm.mode internally. This is not a breaking change for existing merchant integrations.
The CHARGE_CANCEL event type has been renamed to CHARGE_REFUND. If you are matching on webhook event types, update your code:
# BEFORE (1.x)
when Jamm::OpenAPI::EventType::CHARGE_CANCEL
# AFTER (2.0.0)
when Jamm::OpenAPI::EventType::CHARGE_REFUND 👈️👈️👈️The Jamm::Charge module, deprecated since v1.4.0, has been permanently removed. All deprecated methods are no longer available:
-
Jamm::Charge.create_with_redirect→ useJamm::Payment.on_session -
Jamm::Charge.create_without_redirect→ useJamm::Payment.off_session -
Jamm::Charge.get→ useJamm::Payment.get -
Jamm::Charge.list→ useJamm::Payment.list
On Session Payment now supports one-time payment mode.
Jamm::Payment.on_session(
one_time: true, 👈️👈️👈️
buyer: Jamm::OpenAPI::Buyer.new(
email: 'foo@example.com',
name: 'Yamada Taro',
force_kyc: true,
katakana_last_name: 'ヤマダ',
katakana_first_name: 'タロウ',
address: 'Tokyo, Minato-ku 1-2-3',
birth_date: '2000-01-23',
gender: 'male',
metadata: {},
),
charge: Jamm::OpenAPI::InitialCharge.new(
price: 1000,
description: 'Test payment',
metadata: {},
),
redirect: Jamm::OpenAPI::URL.new(
success_url: 'https://jamm-pay.jp/success',
failure_url: 'https://jamm-pay.jp/fail',
)
)customer.update() methods now supports updating customer (buyer) email and phone number.
Jamm::Customer.update('cus-12345', {
email: 'new-email-address@example.com',
phone: '09012345678',
})Please check out Customer Update Parameters for more information.
Added a new link_initiated field to the Jamm::Customer.get response that indicates whether a payment link associated with this customer has been clicked or initialized.
Please check Customer object for more information.
Redirect links are now optional. If a redirect link is provided, the user will be redirected, otherwise they will remain on the same page.
# On Session Payment with redirect object.
Jamm::Payment.on_session(
buyer: Jamm::OpenAPI::Buyer.new(
email: 'foo@example.com',
name: 'Yamada Taro',
force_kyc: true,
katakana_last_name: 'ヤマダ',
katakana_first_name: 'タロウ',
address: 'Tokyo, Minato-ku 1-2-3',
birth_date: '2000-01-23',
gender: 'male',
metadata: {},
),
charge: Jamm::OpenAPI::InitialCharge.new(
price: 1000,
description: 'Test payment',
metadata: {},
),
# Only set this object when merchant wants to redirect
# user back after completing payment approval.
redirect: Jamm::OpenAPI::URL.new( 👈️👈️👈️
success_url: 'https://jamm-pay.jp/success',
failure_url: 'https://jamm-pay.jp/fail',
)
)
# On Session Payment without redirect object.
Jamm::Payment.on_session(
buyer: Jamm::OpenAPI::Buyer.new(
email: 'foo@example.com',
name: 'Yamada Taro',
force_kyc: true,
katakana_last_name: 'ヤマダ',
katakana_first_name: 'タロウ',
address: 'Tokyo, Minato-ku 1-2-3',
birth_date: '2000-01-23',
gender: 'male',
metadata: {},
),
charge: Jamm::OpenAPI::InitialCharge.new(
price: 1000,
description: 'Test payment',
metadata: {},
),
# Omit redirect object when merchant does not need to
# bring user back to website after payment approval.
)We are deprecating some methods from older versions. You will see deprecation warning when those methods are called, and we will remove them entirely from our backend in future versions. Once it's removed from our backend, all method calls will return HTTP error.
Please follow our migration guide in below to transition to our latest methods.
- Jamm::Charge::create_with_redirect
- Jamm::Charge::create_without_redirect
- Jamm::Charge::get
- Jamm::Charge::list
This method was supposed to provide Payment Link to bring customer to Jamm application to confirm and approve their payment.
Ruby SDK 1.4.0 start to provide such functionality through Jamm::Payment.on_session method.
If you are creating Payment Link for new customer, you should have buyer object attached.
The input structure is exactly the same, just swap the method call.
# DEPRECATING
Jamm::Charge.create_with_redirect(
buyer: Jamm::OpenAPI::Buyer.new(
email: 'foo@example.com',
name: 'Yamada Taro',
force_kyc: true,
katakana_last_name: 'ヤマダ',
katakana_first_name: 'タロウ',
address: 'Tokyo, Minato-ku 1-2-3',
birth_date: '2000-01-23',
gender: 'male',
metadata: {},
),
charge: Jamm::OpenAPI::InitialCharge.new(
price: 1000,
description: 'Test payment',
metadata: {},
),
redirect: Jamm::OpenAPI::URL.new(
success_url: 'https://jamm-pay.jp/success',
failure_url: 'https://jamm-pay.jp/fail'
)
)
# NEW
Jamm::Payment.on_session( 👈️👈️👈️
buyer: Jamm::OpenAPI::Buyer.new(
email: 'foo@example.com',
name: 'Yamada Taro',
force_kyc: true,
katakana_last_name: 'ヤマダ',
katakana_first_name: 'タロウ',
address: 'Tokyo, Minato-ku 1-2-3',
birth_date: '2000-01-23',
gender: 'male',
metadata: {},
),
charge: Jamm::OpenAPI::InitialCharge.new(
price: 1000,
description: 'Test payment',
metadata: {},
),
redirect: Jamm::OpenAPI::URL.new(
success_url: 'https://jamm-pay.jp/success',
failure_url: 'https://jamm-pay.jp/fail',
)
)If you are creating Payment Link for the existing customer, you should have customer object attached.
The input structure is exactly the same, just swap the method call.
# DEPRECATING
Jamm::Charge.create_with_redirect(
customer: 'cus-12345',
charge: Jamm::OpenAPI::InitialCharge.new(
price: 1000,
description: 'Test payment',
metadata: {},
),
redirect: Jamm::OpenAPI::URL.new(
success_url: 'https://jamm-pay.jp/success',
failure_url: 'https://jamm-pay.jp/fail',
)
)
# NEW
Jamm::Payment.on_session( 👈️👈️👈️
customer: 'cus-12345',
charge: Jamm::OpenAPI::InitialCharge.new(
price: 1000,
description: 'Test payment',
metadata: {},
),
redirect: Jamm::OpenAPI::URL.new(
success_url: 'https://jamm-pay.jp/success',
failure_url: 'https://jamm-pay.jp/fail'
)
)This method was supposed to immediately withdraw money from the existing customer's bank account.
Ruby SDK 1.4.0 start to provide such functionality through Jamm::Payment.off_session method.
# DEPRECATING
Jamm::Charge.create_without_redirect(
customer: 'cus-12345',
charge: Jamm::OpenAPI::InitialCharge.new(
price: 1000,
description: 'Test payment',
metadata: {},
)
)
# NEW
Jamm::Payment.off_session( 👈️👈️👈️
customer: 'cus-12345',
charge: Jamm::OpenAPI::InitialCharge.new(
price: 1000,
description: 'Test payment',
metadata: {},
)
)# DEPRECATING
Jamm::Charge.get('chg-12345')
# NEW
Jamm::Payment.get('chg-12345') 👈️👈️👈️# DEPRECATING
Jamm::Charge.list(
customer: 'cus-12345',
)
# NEW
Jamm::Payment.list( 👈️👈️👈️
customer: 'cus-12345',
)