ledger

command module
v0.0.0-...-307a5c9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 21, 2023 License: MIT Imports: 14 Imported by: 0

README

Ledger

It is a conceptual Ledger for storing payments. It exposes the following endpoints over gRPC:

  • CreatePayment to create a new payment.
  • ReadPayment to get all information about a payment.
  • ReadPaymentUsingBankReference to get all information about a payment using the bank reference.
  • UpdatePaymentToPending to inform that a payment was sent to an Acquiring Bank.
  • UpdatePaymentToSuccess to inform that a payment was successfully executed by an Acquiring Bank.
  • UpdatePaymentToFail to set the payment as a failure, if refused by the bank, a message is expected to infrom the reason.

The validation of fields is very simple, it is not truly checking credit card number, or currencies. The idea is to get something minimal working, but that can be extended and improved later.

Data Model

Internally there is an in memory database which is a hash table with all payments keyed by their ids, and an extra hash table to map bank reference ids to the ledger ids. The idea is that the bank will issue an id of its own while processing the payment.

type Payment struct {
	ID               uuid.UUID
	MerchantID       uuid.UUID
	Amount           float64
	Currency         string
	PurchaseTime     time.Time
	ValidationMethod string
	Card             CreditCard
	Metadata         string
	Status           PaymentStatus
	BankPaymentID    uuid.UUID
	BankRequestTime  time.Time
	BankResponseTime time.Time
	BankMessage      string
}

Testing

Unit tests

Please run the unit tests as follows:

$ go test -v ./... -coverprofile=coverage.out

And check the coverage (currently ~74%):

$ go tool cover -func=coverage.out
Manual testing

These tests should later be automated as integrations tests, but for now please use the grpcurl tool to verify that the endpoints are working as expected.

  • Create a valid payment
$ grpcurl -plaintext -d '{"merchant_id": "e1211351-bb91-441f-9ea0-3b243189dec6", "amount": 150.0, "currency": "USD", "purchase_time_utc": "2023-05-18T05:00:10.000", "validation_method": "sms", "card": {"number": "1111-2222-3333-4444", "name": "name surname", "expire_month": 10, "expire_year": 2099, "cvv": 123}, "metadata": "shopper:123"}' "0.0.0.0:50053" ledger.LedgerService/CreatePayment
{
  "id": "35947b97-1cf3-4f5c-aa23-3ee0b9734ff7"
}
  • Create an invalid payment - negative amount
$ grpcurl -plaintext -d '{"merchant_id": "e1211351-bb91-441f-9ea0-3b243189dec6", "amount": -150.0, "currency": "USD", "purchase_time_utc": "2023-05-18T05:00:10.000", "validation_method": "sms", "card": {"number": "1111-2222-3333-4444", "name": "name surname", "expire_month": 10, "expire_year": 2099, "cvv": 123}, "metadata": "shopper:123"}' "0.0.0.0:50053" ledger.LedgerService/CreatePayment
ERROR:
  Code: Unknown
  Message: negative amount
  • Create an invalid payment - card expired
$ grpcurl -plaintext -d '{"merchant_id": "e1211351-bb91-441f-9ea0-3b243189dec6", "amount": 150.0, "currency": "USD", "purchase_time_utc": "2023-05-18T05:00:10.000", "validation_method": "sms", "card": {"number": "1111-2222-3333-4444", "name": "name surname", "expire_month": 10, "expire_year": 2020, "cvv": 123}, "metadata": "shopper:123"}' "0.0.0.0:50053" ledger.LedgerService/CreatePayment
ERROR:
  Code: Unknown
  Message: invalid expiration
  • Read existing payment
$ grpcurl -plaintext -d '{"id": "35947b97-1cf3-4f5c-aa23-3ee0b9734ff7"}' "0.0.0.0:50053" ledger.LedgerService/ReadPayment
{
  "payment": {
    "id": "35947b97-1cf3-4f5c-aa23-3ee0b9734ff7",
    "merchantId": "e1211351-bb91-441f-9ea0-3b243189dec6",
    "amount": 150,
    "currency": "USD",
    "purchaseTimeUtc": "2023-05-18T05:00:10.000",
    "validationMethod": "sms",
    "card": {
      "number": "1111-2222-3333-4444",
      "name": "name surname",
      "expireMonth": 10,
      "expireYear": 2099,
      "cvv": 123
    },
    "metadata": "shopper:123",
    "bankPaymentId": "00000000-0000-0000-0000-000000000000",
    "bankRequestTimeUtc": "0001-01-01T00:00:00.000",
    "bankResponseTimeUtc": "0001-01-01T00:00:00.000"
  }
}
  • Read unexisting payment
$ grpcurl -plaintext -d '{"id": "e1211351-bb91-441f-9ea0-3b243189dec6"}' "0.0.0.0:50053" ledger.LedgerService/ReadPayment
ERROR:
  Code: Unknown
  Message: there is no payment with given id
  • Update payment to pending
$ grpcurl -plaintext -d '{"id": "35947b97-1cf3-4f5c-aa23-3ee0b9734ff7", "bank_payment_id": "70580f0a-8478-4aba-8ccf-3de1e1df665c", "bank_request_time_utc": "2023-05-18T05:01:10.000"}' "0.0.0.0:50053" ledger.LedgerService/UpdatePaymentToPending
{

}
$ grpcurl -plaintext -d '{"id": "35947b97-1cf3-4f5c-aa23-3ee0b9734ff7"}' "0.0.0.0:50053" ledger.LedgerService/ReadPayment
{
  "payment": {
    "id": "35947b97-1cf3-4f5c-aa23-3ee0b9734ff7",
    "merchantId": "e1211351-bb91-441f-9ea0-3b243189dec6",
    "amount": 150,
    "currency": "USD",
    "purchaseTimeUtc": "2023-05-18T05:00:10.000",
    "validationMethod": "sms",
    "card": {
      "number": "1111-2222-3333-4444",
      "name": "name surname",
      "expireMonth": 10,
      "expireYear": 2099,
      "cvv": 123
    },
    "metadata": "shopper:123",
    "status": "PENDING",
    "bankPaymentId": "70580f0a-8478-4aba-8ccf-3de1e1df665c",
    "bankRequestTimeUtc": "2023-05-18T05:01:10.000",
    "bankResponseTimeUtc": "0001-01-01T00:00:00.000"
  }
}
  • Update payment to success
$ grpcurl -plaintext -d '{"id": "35947b97-1cf3-4f5c-aa23-3ee0b9734ff7", "bank_payment_id": "70580f0a-8478-4aba-8ccf-3de1e1df665c", "bank_response_time_utc": "2023-05-18T05:02:10.000", "bank_message": "success"}' "0.0.0.0:50053" ledger.LedgerService/UpdatePaymentToSuccess
{

}
$ grpcurl -plaintext -d '{"id": "35947b97-1cf3-4f5c-aa23-3ee0b9734ff7"}' "0.0.0.0:50053" ledger.LedgerService/ReadPayment
{
  "payment": {
    "id": "35947b97-1cf3-4f5c-aa23-3ee0b9734ff7",
    "merchantId": "e1211351-bb91-441f-9ea0-3b243189dec6",
    "amount": 150,
    "currency": "USD",
    "purchaseTimeUtc": "2023-05-18T05:00:10.000",
    "validationMethod": "sms",
    "card": {
      "number": "1111-2222-3333-4444",
      "name": "name surname",
      "expireMonth": 10,
      "expireYear": 2099,
      "cvv": 123
    },
    "metadata": "shopper:123",
    "status": "SUCCESS",
    "bankPaymentId": "70580f0a-8478-4aba-8ccf-3de1e1df665c",
    "bankRequestTimeUtc": "2023-05-18T05:01:10.000",
    "bankResponseTimeUtc": "2023-05-18T05:02:10.000",
    "bankMessage": "success"
  }
}
  • Update payment to fail
$ grpcurl -plaintext -d '{"merchant_id": "e1211351-bb91-441f-9ea0-3b243189dec6", "amount": 150.0, "currency": "USD", "purchase_time_utc": "2023-05-18T05:00:10.000", "validation_method": "sms", "card": {"number": "1111-2222-3333-4444", "name": "name surname", "expire_month": 10, "expire_year": 2029, "cvv": 123}, "metadata": "shopper:123"}' "0.0.0.0:50053" ledger.LedgerService/CreatePayment
{
  "id": "dbb2c818-ec5f-4dac-ad2a-a6b021c981bf"
}
$ grpcurl -plaintext -d '{"id": "dbb2c818-ec5f-4dac-ad2a-a6b021c981bf", "bank_payment_id": "70580f0a-8478-4aba-8ccf-3de1e1df665c", "bank_response_time_utc": "2023-05-18T05:02:10.000", "bank_message": "could not reach shopper"}' "0.0.0.0:50053" ledger.LedgerService/UpdatePaymentToFail
{

}
$ grpcurl -plaintext -d '{"id": "dbb2c818-ec5f-4dac-ad2a-a6b021c981bf"}' "0.0.0.0:50053" ledger.LedgerService/ReadPayment
{
  "payment": {
    "id": "dbb2c818-ec5f-4dac-ad2a-a6b021c981bf",
    "merchantId": "e1211351-bb91-441f-9ea0-3b243189dec6",
    "amount": 150,
    "currency": "USD",
    "purchaseTimeUtc": "2023-05-18T05:00:10.000",
    "validationMethod": "sms",
    "card": {
      "number": "1111-2222-3333-4444",
      "name": "name surname",
      "expireMonth": 10,
      "expireYear": 2029,
      "cvv": 123
    },
    "metadata": "shopper:123",
    "status": "FAIL",
    "bankPaymentId": "70580f0a-8478-4aba-8ccf-3de1e1df665c",
    "bankRequestTimeUtc": "0001-01-01T00:00:00.000",
    "bankResponseTimeUtc": "2023-05-18T05:02:10.000",
    "bankMessage": "could not reach shopper"
  }
}
  • Read using bank payment id
$ grpcurl -plaintext -d '{"merchant_id": "e1211351-bb91-441f-9ea0-3b243189dec6", "amount": 150.0, "currency": "USD", "purchase_time_utc": "2023-05-18T05:00:10.000", "validation_method": "sms", "card": {"number": "1111-2222-3333-4444", "name": "name surname", "expire_month": 10, "expire_year": 2029, "cvv": 123}, "metadata": "shopper:123"}' "0.0.0.0:50053" ledger.LedgerService/CreatePayment
{
  "id": "ac5503cc-3018-4484-90e1-0bcc64c91f63"
}
$ grpcurl -plaintext -d '{"id": "ac5503cc-3018-4484-90e1-0bcc64c91f63", "bank_payment_id": "70580f0a-8478-4aba-8ccf-3de1e1df665c", "bank_response_time_utc": "2023-05-18T05:02:10.000", "bank_message": "success"}' "0.0.0.0:50053" ledger.LedgerService/UpdatePaymentToSuccess
{

}
$ grpcurl -plaintext -d '{"id": "70580f0a-8478-4aba-8ccf-3de1e1df665c"}' "0.0.0.0:50053" ledger.LedgerService/ReadPaymentUsingBankReference
{
  "payment": {
    "id": "ac5503cc-3018-4484-90e1-0bcc64c91f63",
    "merchantId": "e1211351-bb91-441f-9ea0-3b243189dec6",
    "amount": 150,
    "currency": "USD",
    "purchaseTimeUtc": "2023-05-18T05:00:10.000",
    "validationMethod": "sms",
    "card": {
      "number": "1111-2222-3333-4444",
      "name": "name surname",
      "expireMonth": 10,
      "expireYear": 2029,
      "cvv": 123
    },
    "metadata": "shopper:123",
    "status": "SUCCESS",
    "bankPaymentId": "70580f0a-8478-4aba-8ccf-3de1e1df665c",
    "bankRequestTimeUtc": "0001-01-01T00:00:00.000",
    "bankResponseTimeUtc": "2023-05-18T05:02:10.000",
    "bankMessage": "success"
  }
}

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL