Module: Portage::Ucp::PaymentTokenGuard

Defined in:
lib/portage/ucp/payment_token_guard.rb

Overview

PCI boundary guard (§9). complete_checkout's payment_token must be a single-use, tokenized credential from a UCP payment handler / AP2 exchange — never a raw PAN. This can't prove a string is an opaque token, but it can catch the clearest misintegration: something that looks exactly like a card number (digits only, 12-19 characters, Luhn-valid) gets rejected before it ever reaches an Adapter, so a misintegrated agent can't push card numbers through the gem.

Constant Summary collapse

PAN_LENGTHS =
(12..19)

Class Method Summary collapse

Class Method Details

.looks_like_pan?(token) ⇒ Boolean

Returns:

  • (Boolean)


21
22
23
24
25
26
# File 'lib/portage/ucp/payment_token_guard.rb', line 21

def self.looks_like_pan?(token)
  digits = token.to_s
  return false unless digits.match?(/\A\d+\z/) && PAN_LENGTHS.cover?(digits.length)

  luhn_valid?(digits)
end

.validate!(token) ⇒ Object



13
14
15
16
17
18
19
# File 'lib/portage/ucp/payment_token_guard.rb', line 13

def self.validate!(token)
  return unless looks_like_pan?(token)

  raise Portage::Ucp::RawPanRejectedError,
        "payment_token looks like a raw PAN (digits only, Luhn-valid) — " \
        "complete_checkout requires a tokenized credential, never card data"
end