Skip to content

Commit

Permalink
[SDP-962] Change SEP-24 Flow to display different verifications based…
Browse files Browse the repository at this point in the history
… on Disbursement's verification type (#116)

Modify the SEP-24 flow to perform verification for an entered phone number based on the latest verification type.

The current SEP-24 flow is hardcoded to only accept date of birth but we will have disbursement files that will include pin and national id, and the front-end will need to change to be able to parse those values.

Release 1.0.1 to develop (#129)

[Release 1.0.1](#127) to develop

To sync the `main` branch hotfixes:
- #125
- #126

changes:

fix tests

migrate
  • Loading branch information
ziyliu authored and marwen-abid committed Dec 22, 2023
1 parent f67740d commit 90c441b
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 26 deletions.
20 changes: 11 additions & 9 deletions internal/data/disbursement_instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ import (
)

type DisbursementInstruction struct {
Phone string `csv:"phone"`
ID string `csv:"id"`
Amount string `csv:"amount"`
VerificationValue string `csv:"verification"`
Phone string `csv:"phone"`
ID string `csv:"id"`
Amount string `csv:"amount"`
VerificationValue string `csv:"verification"`
ExternalPaymentId *string `csv:"paymentID"`
}

type DisbursementInstructionModel struct {
Expand Down Expand Up @@ -194,11 +195,12 @@ func (di DisbursementInstructionModel) ProcessAll(ctx context.Context, userID st
for _, instruction := range instructions {
receiver := receiverMap[instruction.Phone]
payment := PaymentInsert{
ReceiverID: receiver.ID,
DisbursementID: disbursement.ID,
Amount: instruction.Amount,
AssetID: disbursement.Asset.ID,
ReceiverWalletID: receiverWalletsMap[receiver.ID],
ReceiverID: receiver.ID,
DisbursementID: disbursement.ID,
Amount: instruction.Amount,
AssetID: disbursement.Asset.ID,
ReceiverWalletID: receiverWalletsMap[receiver.ID],
ExternalPaymentID: instruction.ExternalPaymentId,
}
payments = append(payments, payment)
}
Expand Down
29 changes: 29 additions & 0 deletions internal/data/disbursement_instructions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package data

import (
"context"
"database/sql"
"testing"

"github.com/stellar/stellar-disbursement-platform-backend/internal/db"
Expand Down Expand Up @@ -47,16 +48,19 @@ func Test_DisbursementInstructionModel_ProcessAll(t *testing.T) {
VerificationValue: "1990-01-02",
}

externalPaymentID := "abc123"
instruction3 := DisbursementInstruction{
Phone: "+380-12-345-673",
Amount: "100.03",
ID: "123456783",
VerificationValue: "1990-01-03",
ExternalPaymentId: &externalPaymentID,
}
instructions := []*DisbursementInstruction{&instruction1, &instruction2, &instruction3}
expectedPhoneNumbers := []string{instruction1.Phone, instruction2.Phone, instruction3.Phone}
expectedExternalIDs := []string{instruction1.ID, instruction2.ID, instruction3.ID}
expectedPayments := []string{instruction1.Amount, instruction2.Amount, instruction3.Amount}
expectedExternalPaymentIDs := []string{*instruction3.ExternalPaymentId}

disbursementUpdate := &DisbursementUpdate{
ID: disbursement.ID,
Expand Down Expand Up @@ -91,6 +95,9 @@ func Test_DisbursementInstructionModel_ProcessAll(t *testing.T) {
actualPayments := GetPaymentsByDisbursementID(t, ctx, dbConnectionPool, disbursement.ID)
assert.Equal(t, expectedPayments, actualPayments)

actualExternalPaymentIDs := GetExternalPaymentIDsByDisbursementID(t, ctx, dbConnectionPool, disbursement.ID)
assert.Equal(t, expectedExternalPaymentIDs, actualExternalPaymentIDs)

// Verify Disbursement
actualDisbursement, err := di.disbursementModel.Get(ctx, dbConnectionPool, disbursement.ID)
require.NoError(t, err)
Expand Down Expand Up @@ -304,3 +311,25 @@ func GetPaymentsByDisbursementID(t *testing.T, ctx context.Context, dbConnection
require.NoError(t, err)
return payments
}

func GetExternalPaymentIDsByDisbursementID(t *testing.T, ctx context.Context, dbConnectionPool db.DBConnectionPool, disbursementID string) []string {
query := `
SELECT
p.external_payment_id
FROM
payments p
WHERE p.disbursement_id = $1
`
var externalPaymentIDRefs []sql.NullString
err := dbConnectionPool.SelectContext(ctx, &externalPaymentIDRefs, query, disbursementID)
require.NoError(t, err)

var externalPaymentIDs []string
for _, v := range externalPaymentIDRefs {
if v.String != "" {
externalPaymentIDs = append(externalPaymentIDs, v.String)
}
}

return externalPaymentIDs
}
6 changes: 3 additions & 3 deletions internal/data/disbursements_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -437,9 +437,9 @@ func Test_DisbursementModel_Update(t *testing.T) {
})

disbursementFileContent := CreateInstructionsFixture(t, []*DisbursementInstruction{
{"1234567890", "1", "123.12", "1995-02-20"},
{"0987654321", "2", "321", "1974-07-19"},
{"0987654321", "3", "321", "1974-07-19"},
{"1234567890", "1", "123.12", "1995-02-20", nil},
{"0987654321", "2", "321", "1974-07-19", nil},
{"0987654321", "3", "321", "1974-07-19", nil},
})

t.Run("update instructions", func(t *testing.T) {
Expand Down
10 changes: 5 additions & 5 deletions internal/data/fixtures_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ func Test_Fixtures_CreateInstructionsFixture(t *testing.T) {

t.Run("writes records correctly", func(t *testing.T) {
instructions := []*DisbursementInstruction{
{"1234567890", "1", "123.12", "1995-02-20"},
{"0987654321", "2", "321", "1974-07-19"},
{"1234567890", "1", "123.12", "1995-02-20", nil},
{"0987654321", "2", "321", "1974-07-19", nil},
}
buf := CreateInstructionsFixture(t, instructions)
lines := strings.Split(string(buf), "\n")
Expand All @@ -116,9 +116,9 @@ func Test_Fixtures_UpdateDisbursementInstructionsFixture(t *testing.T) {
})

instructions := []*DisbursementInstruction{
{"1234567890", "1", "123.12", "1995-02-20"},
{"0987654321", "2", "321", "1974-07-19"},
{"0987654321", "3", "321", "1974-07-19"},
{"1234567890", "1", "123.12", "1995-02-20", nil},
{"0987654321", "2", "321", "1974-07-19", nil},
{"0987654321", "3", "321", "1974-07-19", nil},
}

t.Run("update instructions", func(t *testing.T) {
Expand Down
22 changes: 14 additions & 8 deletions internal/data/payments.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type Payment struct {
ReceiverWallet *ReceiverWallet `json:"receiver_wallet,omitempty" db:"receiver_wallet"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
ExternalPaymentID *string `json:"external_payment_id,omitempty" db:"external_payment_id"`
}

type PaymentStatusHistoryEntry struct {
Expand All @@ -50,11 +51,12 @@ var (
)

type PaymentInsert struct {
ReceiverID string `db:"receiver_id"`
DisbursementID string `db:"disbursement_id"`
Amount string `db:"amount"`
AssetID string `db:"asset_id"`
ReceiverWalletID string `db:"receiver_wallet_id"`
ReceiverID string `db:"receiver_id"`
DisbursementID string `db:"disbursement_id"`
Amount string `db:"amount"`
AssetID string `db:"asset_id"`
ReceiverWalletID string `db:"receiver_wallet_id"`
ExternalPaymentID *string `db:"external_payment_id"`
}

type PaymentUpdate struct {
Expand Down Expand Up @@ -150,6 +152,7 @@ func (p *PaymentModel) Get(ctx context.Context, id string, sqlExec db.SQLExecute
p.status_history,
p.created_at,
p.updated_at,
p.external_payment_id,
d.id as "disbursement.id",
d.name as "disbursement.name",
d.status as "disbursement.status",
Expand Down Expand Up @@ -227,6 +230,7 @@ func (p *PaymentModel) GetAll(ctx context.Context, queryParams *QueryParams, sql
p.status_history,
p.created_at,
p.updated_at,
p.external_payment_id,
d.id as "disbursement.id",
d.name as "disbursement.name",
d.status as "disbursement.status",
Expand Down Expand Up @@ -341,18 +345,20 @@ func (p *PaymentModel) InsertAll(ctx context.Context, sqlExec db.SQLExecuter, in
asset_id,
receiver_id,
disbursement_id,
receiver_wallet_id
receiver_wallet_id,
external_payment_id
) VALUES (
$1,
$2,
$3,
$4,
$5
$5,
$6
)
`

for _, payment := range inserts {
_, err := sqlExec.ExecContext(ctx, query, payment.Amount, payment.AssetID, payment.ReceiverID, payment.DisbursementID, payment.ReceiverWalletID)
_, err := sqlExec.ExecContext(ctx, query, payment.Amount, payment.AssetID, payment.ReceiverID, payment.DisbursementID, payment.ReceiverWalletID, payment.ExternalPaymentID)
if err != nil {
return fmt.Errorf("error inserting payment: %w", err)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-- +migrate Up

ALTER TABLE public.payments
ADD COLUMN external_payment_id VARCHAR(64) NULL;

-- +migrate Down

ALTER TABLE public.payments
DROP COLUMN external_payment_id;
2 changes: 1 addition & 1 deletion internal/serve/httphandler/payments_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ func Test_PaymentsHandlerGet(t *testing.T) {
"invitation_sent_at": null
},
"created_at": %q,
"updated_at": %q
"updated_at": %q
}`, payment.ID, payment.StellarTransactionID, payment.StellarOperationID, payment.StatusHistory[0].Timestamp.Format(time.RFC3339Nano),
disbursement.ID, disbursement.CreatedAt.Format(time.RFC3339Nano), disbursement.UpdatedAt.Format(time.RFC3339Nano),
asset.ID, receiverWallet.ID, receiver.ID, wallet.ID, receiverWallet.StellarAddress, receiverWallet.StellarMemo,
Expand Down

0 comments on commit 90c441b

Please sign in to comment.