Skip to content
Open
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
4 changes: 4 additions & 0 deletions .cspell/custom-words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,14 @@ Payoneer
paypal
Payplug
pids
PISP
pisp
pmezard
proguard
Proguard
prometheus
protoc
pyca
pyflow
pymdownx
pypa
Expand All @@ -149,6 +152,7 @@ ropeproject
RPCURL
Rulebook
screenreaders
SECP
setlocal
sharedpref
Shopcider
Expand Down
5 changes: 4 additions & 1 deletion code/sdk/python/ap2/sdk/receipt_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,10 @@ def verify_receipt(

# 2. Verify receipt reference exists in the issuer's store
receipt_reference = getattr(receipt.root, 'reference', None)
if not has_reference_in_store_cb(receipt_reference):
if (
has_reference_in_store_cb is not None
and not has_reference_in_store_cb(receipt_reference)
):
_logger.warning(
'Receipt reference not found in store: %s',
receipt_reference,
Expand Down
104 changes: 104 additions & 0 deletions code/sdk/python/ap2/tests/receipt_wrapper_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,63 @@ def test_verify_payment_receipt_success(issuer_key, issuer_public_key):
has_ref_cb.assert_called_once_with(reference)


def test_verify_payment_receipt_success_without_store_cb(
issuer_key, issuer_public_key
):
"""Test verification of a payment receipt when reference callback is omitted."""
client = ReceiptClient()
reference = 'ref_123'
base_receipt = client._create_base_receipt(
'Success', 'issuer.com', reference
)
payment_receipt = PaymentReceipt(
**base_receipt,
payment_id='pid_123',
psp_confirmation_id='pid_123',
network_confirmation_id='pid_123',
)
receipt_jwt = create_jwt(
{'alg': 'ES256'}, payment_receipt.model_dump(), issuer_key
)

result = client.verify_receipt(
receipt_jwt=receipt_jwt,
receipt_issuer_public_key=issuer_public_key,
is_payment_receipt=True,
)

assert result == {'verified': True}


def test_verify_payment_receipt_success_explicit_none_cb(
issuer_key, issuer_public_key
):
"""Test verification of a payment receipt when reference callback is explicitly None."""
client = ReceiptClient()
reference = 'ref_123'
base_receipt = client._create_base_receipt(
'Success', 'issuer.com', reference
)
payment_receipt = PaymentReceipt(
**base_receipt,
payment_id='pid_123',
psp_confirmation_id='pid_123',
network_confirmation_id='pid_123',
)
receipt_jwt = create_jwt(
{'alg': 'ES256'}, payment_receipt.model_dump(), issuer_key
)

result = client.verify_receipt(
receipt_jwt=receipt_jwt,
receipt_issuer_public_key=issuer_public_key,
has_reference_in_store_cb=None,
is_payment_receipt=True,
)

assert result == {'verified': True}


def test_verify_checkout_receipt_success(issuer_key, issuer_public_key):
"""Test successful verification of a checkout receipt."""
client = ReceiptClient()
Expand All @@ -133,6 +190,53 @@ def test_verify_checkout_receipt_success(issuer_key, issuer_public_key):
has_ref_cb.assert_called_once_with(reference)


def test_verify_checkout_receipt_success_without_store_cb(
issuer_key, issuer_public_key
):
"""Test verification of a checkout receipt when reference callback is omitted."""
client = ReceiptClient()
reference = 'ref_456'
base_receipt = client._create_base_receipt(
'Success', 'merchant.com', reference
)
checkout_receipt = CheckoutReceipt(**base_receipt, order_id='order_456')
receipt_jwt = create_jwt(
{'alg': 'ES256'}, checkout_receipt.model_dump(), issuer_key
)

result = client.verify_receipt(
receipt_jwt=receipt_jwt,
receipt_issuer_public_key=issuer_public_key,
is_payment_receipt=False,
)

assert result == {'verified': True}


def test_verify_checkout_receipt_success_explicit_none_cb(
issuer_key, issuer_public_key
):
"""Test verification of a checkout receipt when reference callback is explicitly None."""
client = ReceiptClient()
reference = 'ref_456'
base_receipt = client._create_base_receipt(
'Success', 'merchant.com', reference
)
checkout_receipt = CheckoutReceipt(**base_receipt, order_id='order_456')
receipt_jwt = create_jwt(
{'alg': 'ES256'}, checkout_receipt.model_dump(), issuer_key
)

result = client.verify_receipt(
receipt_jwt=receipt_jwt,
receipt_issuer_public_key=issuer_public_key,
has_reference_in_store_cb=None,
is_payment_receipt=False,
)

assert result == {'verified': True}


def test_verify_receipt_invalid_signature(issuer_public_key):
"""Test verification failure with an invalid signature."""
client = ReceiptClient()
Expand Down
Loading