Skip to content

neronguyenvn/CardQRPaymentSample

Repository files navigation

Card / QR Payment Sample (Android – Kotlin)

Overview

This project demonstrates a realistic Android payment flow for Card / QR payments in POS-like devices, focusing on reliability, security, and correctness rather than UI or backend complexity.

The goal is to showcase real-world payment concepts such as idempotency, retry safety, partial payments, offline handling, and Android security best practices.


Design Philosophy

This project intentionally prioritizes:

  • Correct payment modeling
  • Clear separation of responsibilities
  • Testability

Over:

  • UI complexity
  • Business-specific logic
  • Infrastructure details

Payment Concepts

Payment Intent

A PaymentIntent represents a single logical intent to pay a given amount using a specific payment method.

It exists before any financial transaction happens and survives:

  • Network failures
  • App restarts
  • Retry attempts

This concept is used in real payment systems (e.g. Stripe).


Transaction ID vs Idempotency Key

Idempotency Key

  • Generated by the client before charging
  • Identifies a single payment intent
  • Ensures retry does not cause double charge

Transaction ID

  • Generated by the payment gateway after processing
  • Identifies the actual financial transaction
  • Used for audit, reconciliation, or refund

Keeping them separate is critical for safe payment retries.


Partial Payment

An order may be fulfilled by multiple PaymentIntents, each representing an atomic payment attempt using a specific payment method.

Each PaymentIntent is either fully successful or failed. The order tracks the accumulated paid amount and the remaining amount to be paid.


Retry & Offline Handling

  • Payment state is persisted locally (encrypted)
  • The same idempotency key is reused for retries
  • Retrying a payment never creates a new transaction
  • Offline payments are queued and retried when network is restored

This guarantees exactly-once execution from the user’s perspective.


Security Considerations

This project follows Android security best practices for payment apps:

  • Android Keystore for key storage
  • EncryptedSharedPreferences and Room for local persistence
  • No sensitive card or PIN data is logged or stored
  • One-time tokens instead of raw payment data
  • ProGuard / R8 obfuscation enabled

Cryptographic operations such as PIN or PAN encryption are simulated, as they normally belong to device firmware, HSM, or Secure Element layers.


Testing Strategy

Unit Tests

  • Payment use cases
  • ViewModel state transitions
  • Retry and idempotency behavior in repositories

Fake Payment Gateway

  • Stateful idempotency handling
  • Deterministic responses for:
    • Success
    • Failure

No real card, QR, or banking systems are used.


CI

  • GitHub Actions
  • Gradle build
  • Unit tests execution
  • No secrets or credentials required

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published