Skip to content

Commit 7322764

Browse files
author
gitstart_bot
committed
Refactor metadata extraction, fix retryable errors & createdAt format
1 parent f8a5d96 commit 7322764

24 files changed

+308
-306
lines changed

internal/connectors/engine/activities/errors.go

+2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ func (a Activities) temporalPluginErrorCheck(ctx context.Context, err error, isP
4141
return temporal.NewNonRetryableApplicationError(err.Error(), ErrTypeInvalidArgument, err)
4242
case errors.Is(err, models.ErrMissingConnectorMetadata):
4343
return temporal.NewNonRetryableApplicationError(err.Error(), ErrTypeInvalidArgument, err)
44+
case errors.As(err, &models.NonRetryableError):
45+
return temporal.NewNonRetryableApplicationError(err.Error(), ErrTypeInvalidArgument, err)
4446

4547
// Potentially retry
4648
case errors.Is(err, plugins.ErrUpstreamRatelimit):

internal/connectors/engine/activities/plugin_create_bank_account_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ var _ = Describe("Plugin Create Bank Account", func() {
9191
Expect(temporalErr.Type()).To(Equal(activities.ErrTypeInvalidArgument))
9292
},
9393
Entry("wrapped invalid client request", fmt.Errorf("invalid: %w", pluginsError.ErrInvalidClientRequest)),
94-
Entry("connector metadata error custom type", models.NewConnectorMetadataError("some-field")),
94+
Entry("connector metadata error custom type", models.NewConnectorValidationError("some-field", models.ErrMissingConnectorMetadata)),
9595
)
9696
})
9797
})

internal/connectors/plugins/public/gocardless/README.md

+17-9
Original file line numberDiff line numberDiff line change
@@ -56,19 +56,27 @@ The connector supports the following currencies:
5656
Bank accounts can be created for both creditors and customers. The type is determined by metadata in the request:
5757

5858
```json
59+
{ "name": "Gitstart Union Bank",
60+
"accountNumber": "21616901",
61+
"swiftBicCode": "021000021",
62+
"country": "US", // Country code in ISO 3166-1 alpha-2 code.
63+
"metadata": {
64+
"com.gocardless.spec/currency": "USD",
65+
"com.gocardless.spec/customer": "CU001DRQMY17P6",
66+
"com.gocardless.spec/account_type": "savings"
67+
}
68+
}
5969
{
60-
"name": "John Doe",
61-
"accountNumber": "09878762343",
62-
"iban": "2354321234",
63-
"swiftBicCode": "34XZZT34",
70+
"name": "Gitstart Union Bank",
71+
"accountNumber": "21616901",
72+
"swiftBicCode": "021000021",
6473
"country": "US", // Country code in ISO 3166-1 alpha-2 code.
6574
"metadata": {
66-
"branch_code": "required_branch_code",
67-
"currency": "USD",
68-
"creditor": "CR123", // For creditor bank account
75+
"com.gocardless.spec/currency": "USD",
76+
"com.gocardless.spec/creditor": "CR123", // For creditor bank account
6977
// OR
70-
"customer": "CU123", // For customer bank account
71-
"account_type": "savings" // Required for US accounts
78+
"com.gocardless.spec/customer": "CU123", // For customer bank account
79+
"com.gocardless.spec/account_type": "savings" // Required for US accounts
7280
}
7381
}
7482
```

internal/connectors/plugins/public/gocardless/bank_account_creation.go

+2-103
Original file line numberDiff line numberDiff line change
@@ -2,84 +2,11 @@ package gocardless
22

33
import (
44
"context"
5-
"fmt"
65

76
"github.com/formancehq/payments/internal/connectors/plugins/public/gocardless/client"
87
"github.com/formancehq/payments/internal/models"
98
)
109

11-
func validateExternalBankAccount(newExternalBankAccount models.BankAccount) error {
12-
_, err := extractNamespacedMetadata(newExternalBankAccount.Metadata, client.GocardlessBranchCodeMetadataKey)
13-
14-
if err != nil {
15-
return fmt.Errorf("required metadata field com.gocardless.spec/branch_code is missing")
16-
}
17-
18-
reqCurrency, err := extractNamespacedMetadata(newExternalBankAccount.Metadata, client.GocardlessCurrencyMetadataKey)
19-
if err != nil {
20-
return fmt.Errorf("required metadata field com.gocardless.spec/currency is missing")
21-
}
22-
23-
_, ok := SupportedCurrenciesWithDecimal[reqCurrency]
24-
25-
if !ok {
26-
27-
return fmt.Errorf("com.gocardless.spec/currency %s not supported", reqCurrency)
28-
}
29-
30-
creditor, _ := extractNamespacedMetadata(newExternalBankAccount.Metadata, client.GocardlessCreditorMetadataKey)
31-
customer, _ := extractNamespacedMetadata(newExternalBankAccount.Metadata, client.GocardlessCustomerMetadataKey)
32-
33-
if len(creditor) > 1 && creditor[:2] != "CR" {
34-
return fmt.Errorf("com.gocardless.spec/creditor ID must start with 'CR'")
35-
}
36-
37-
if len(customer) > 1 && customer[:2] != "CU" {
38-
return fmt.Errorf("com.gocardless.spec/customer ID must start with 'CU'")
39-
}
40-
41-
if customer == "" && creditor == "" {
42-
return fmt.Errorf("you must provide com.gocardless.spec/customer or com.gocardless.spec/creditor metadata field")
43-
}
44-
45-
if customer != "" && creditor != "" {
46-
return fmt.Errorf("you must provide either com.gocardless.spec/customer or com.gocardless.spec/creditor metadata field but not both")
47-
}
48-
49-
if newExternalBankAccount.Country != nil && *newExternalBankAccount.Country == "US" {
50-
51-
accountType, err := extractNamespacedMetadata(newExternalBankAccount.Metadata, client.GocardlessAccountTypeMetadataKey)
52-
53-
if err != nil {
54-
return fmt.Errorf("required metadata field com.gocardless.spec/account_type is missing")
55-
}
56-
57-
if accountType != "checking" && accountType != "savings" {
58-
return fmt.Errorf("metadata field com.gocardless.spec/account_type must be checking or savings")
59-
60-
}
61-
62-
}
63-
64-
if newExternalBankAccount.AccountNumber == nil {
65-
return fmt.Errorf("account number is required")
66-
}
67-
68-
if newExternalBankAccount.SwiftBicCode == nil {
69-
return fmt.Errorf("swift bic code is required")
70-
}
71-
72-
if newExternalBankAccount.Country == nil {
73-
return fmt.Errorf("country is required")
74-
}
75-
76-
if newExternalBankAccount.IBAN == nil {
77-
return fmt.Errorf("IBAN is required")
78-
}
79-
80-
return nil
81-
}
82-
8310
func (p *Plugin) createBankAccount(ctx context.Context, ba models.BankAccount) (models.CreateBankAccountResponse, error) {
8411
err := validateExternalBankAccount(ba)
8512
if err != nil {
@@ -91,47 +18,19 @@ func (p *Plugin) createBankAccount(ctx context.Context, ba models.BankAccount) (
9118
var externalBankAccount client.GocardlessGenericAccount
9219

9320
if creditor != "" {
94-
creditorBankAccount, err := p.client.CreateCreditorBankAccount(ctx, creditor, ba)
21+
externalBankAccount, err = p.client.CreateCreditorBankAccount(ctx, creditor, ba)
9522

9623
if err != nil {
9724
return models.CreateBankAccountResponse{}, err
9825
}
99-
100-
parsedTime, err := ParseGocardlessTimestamp(creditorBankAccount.CreatedAt)
101-
if err != nil {
102-
return models.CreateBankAccountResponse{}, fmt.Errorf("failed to parse creation time: %w", err)
103-
}
104-
105-
externalBankAccount = client.GocardlessGenericAccount{
106-
ID: creditorBankAccount.Id,
107-
CreatedAt: parsedTime.Unix(),
108-
AccountHolderName: creditorBankAccount.AccountHolderName,
109-
Metadata: creditorBankAccount.Metadata,
110-
Currency: creditorBankAccount.Currency,
111-
AccountType: creditorBankAccount.AccountType,
112-
}
11326
}
11427

11528
if customer != "" {
116-
customerBankAccount, err := p.client.CreateCustomerBankAccount(ctx, customer, ba)
29+
externalBankAccount, err = p.client.CreateCustomerBankAccount(ctx, customer, ba)
11730

11831
if err != nil {
11932
return models.CreateBankAccountResponse{}, err
12033
}
121-
122-
parsedTime, err := ParseGocardlessTimestamp(customerBankAccount.CreatedAt)
123-
if err != nil {
124-
return models.CreateBankAccountResponse{}, fmt.Errorf("failed to parse creation time: %w", err)
125-
}
126-
127-
externalBankAccount = client.GocardlessGenericAccount{
128-
ID: customerBankAccount.Id,
129-
CreatedAt: parsedTime.Unix(),
130-
AccountHolderName: customerBankAccount.AccountHolderName,
131-
Metadata: customerBankAccount.Metadata,
132-
Currency: customerBankAccount.Currency,
133-
AccountType: customerBankAccount.AccountType,
134-
}
13534
}
13635

13736
bankAccount, err := externalAccountFromGocardlessData(externalBankAccount)

0 commit comments

Comments
 (0)