Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion lib/checkout_sdk/issuing/issuing_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,10 @@ def get_card_details(card_id)
# @param [CardUpdateHeaders, nil] headers the optional return-encrypted-cvv and
# Encryption-Key HTTP headers. Setting return_encrypted_cvv without encryption_key returns
# a 422 with error code encryption_key_required.
# @return [OpenStruct] the update response, carrying encrypted_cvv when requested
# @return [OpenStruct] the update response, carrying encrypted_cvv when requested. For a
# virtual card the response may also carry is_single_use (boolean, default false),
# specifying whether the card is set to expire after a single use. Physical cards never
# send it.
def update_card(card_id, update_card_request, headers = nil)
api_client.invoke_patch(
build_path(ISSUING, CARDS, card_id),
Expand Down
19 changes: 13 additions & 6 deletions lib/checkout_sdk/issuing/update_card_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,21 @@ module Issuing
# Example: 2026-06-01T10:00Z
# @return [String]
# @!attribute revocation_date
# Date scheduling the card's automatic revocation.
# [Optional]
# Format: yyyy-MM-dd (time is midnight UTC)
# Example: 2027-03-12
# @return [String]
# @return [String] Date for the card to be automatically revoked, in the form `yyyy-mm-dd`.
# Must be after the current date. Maps swagger `IssuingRevocationDate`.
# @deprecated Use {#scheduled_revocation_date} instead.
# @!attribute scheduled_revocation_date
# @return [String] Date for the card to be automatically revoked, in the form `yyyy-mm-dd`.
# Overrides the deprecated {#revocation_date} when both are given. Maps swagger
# `IssuingScheduledRevocationDate`.
# @!attribute status
# @return [String] Set to `active` to reactivate an `inactive` or `suspended` card.
# Mutually exclusive with `scheduled_activation_date`: submitting both returns a
# `scheduled_activation_date_conflicts_with_activation` error. The only supported
# value is `active`.
class UpdateCardRequest
attr_accessor :reference, :metadata, :expiry_month, :expiry_year,
:scheduled_activation_date, :revocation_date
:scheduled_activation_date, :revocation_date, :scheduled_revocation_date, :status
end
end
end
13 changes: 13 additions & 0 deletions spec/checkout_sdk/issuing/issuing_cards_serialization_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,17 @@ def serialize(request)
expect(headers.return_encrypted_cvv).to eq('true')
end
end

describe 'update_card response' do
# The 2026-09-23 spec update split update-card-response into a virtual/physical
# discriminator; the virtual variant adds is_single_use. This SDK has no typed response
# class for update_card (raw OpenStruct, the same mechanism CheckoutSdk::ApiClient uses),
# so this just confirms the field round-trips through that deserialization.
it 'round-trips is_single_use for a virtual card response' do
body = '{"type":"virtual","last_modified_date":"2026-06-01T10:00:00Z","is_single_use":true}'
response = JSON.parse(body, object_class: OpenStruct)

expect(response.is_single_use).to eq(true)
end
end
end
Loading