Skip to content

Commit 8ee75ad

Browse files
authored
feat: add card issuing (#273)
* Add card issuing * Add issuing authorizations * Add issuing transactions
1 parent d29aa76 commit 8ee75ad

File tree

7 files changed

+719
-0
lines changed

7 files changed

+719
-0
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package cardissuing
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/moovfinancial/moov-go/pkg/moov"
8+
9+
"github.com/stretchr/testify/require"
10+
)
11+
12+
// Card issuing is currently in a closed beta. Contact Moov for more information.
13+
func TestCardIssuing(t *testing.T) {
14+
// Step 1: create Moov client and set some variables
15+
16+
// The following code shows how you can configure the moov client with
17+
// your credentials, if you don't want to use environment variables.
18+
// However, it is recommended to load the credentials from the
19+
// configuration file.
20+
21+
mc, err := moov.NewClient() // reads credentials from Environmental variables by default
22+
require.NoError(t, err)
23+
24+
// Create a new context or use an existing one
25+
ctx := context.Background()
26+
27+
// Ping the server to check credentials
28+
err = mc.Ping(ctx)
29+
require.NoError(t, err)
30+
31+
// Step 2: create account for the user
32+
33+
// For now just using a known existing account that is already allowed in the closed beta for card issuing
34+
accountID := "ebbf46c6-122a-4367-bc45-7dd555e1d3b9"
35+
36+
// Step 3: enable the card-issuing capability for the account
37+
38+
// Can skip this step if the card-issuing capability has already previously been enabled for the account
39+
40+
_, err = mc.RequestCapabilities(ctx, accountID, []moov.CapabilityName{
41+
"card-issuing",
42+
})
43+
require.NoError(t, err)
44+
45+
// Step 4: get the source wallet for funding the issued card
46+
47+
// For now just using a known existing wallet for the account
48+
walletID := "4dbac313-d505-4d51-a0fe-c11787916fcf"
49+
50+
// Step 5: create an issued card
51+
52+
memo := "example"
53+
create := moov.CreateIssuedCard{
54+
FundingWalletID: walletID,
55+
AuthorizedUser: moov.CreateAuthorizedUser{
56+
FirstName: "John",
57+
LastName: "Doe",
58+
},
59+
FormFactor: moov.IssuedCardFormFactor_Virtual,
60+
Memo: &memo,
61+
}
62+
created, err := mc.CreateIssuedCard(ctx, accountID, create)
63+
require.NoError(t, err)
64+
t.Cleanup(func() {
65+
require.NoError(t, closeIssuedCard(ctx, mc, accountID, created.IssuedCardID))
66+
})
67+
}
68+
69+
func closeIssuedCard(ctx context.Context, mc *moov.Client, accountID, cardID string) error {
70+
closed := moov.UpdateIssuedCardState_Closed
71+
update := moov.UpdateIssuedCard{
72+
State: &closed,
73+
}
74+
return mc.UpdateIssuedCard(ctx, accountID, cardID, update)
75+
}

internal/testtools/const.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ const PARTNER_WALLET_PM_ID = "041fdc88-c93d-4cb4-80aa-b2dde9a4fe2e"
55

66
const MERCHANT_ID = "ebbf46c6-122a-4367-bc45-7dd555e1d3b9"
77
const MERCHANT_WALLET_PM_ID = "67ebda6c-de48-474c-b49d-2cd3aa7d3f92"
8+
const MERCHANT_WALLET_ID = "4dbac313-d505-4d51-a0fe-c11787916fcf"

pkg/moov/a_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ import (
1818
const FACILITATOR_ID = testtools.PARTNER_ID
1919
const FACILITATOR_WALLET_PM_ID = testtools.PARTNER_WALLET_PM_ID
2020

21+
const MERCHANT_ID = testtools.MERCHANT_ID
2122
const MERCHANT_WALLET_PM_ID = testtools.MERCHANT_WALLET_PM_ID
23+
const MERCHANT_WALLET_ID = testtools.MERCHANT_WALLET_ID
2224

2325
func getLincolnBank(t *testing.T, mc *moov.Client) *moov.Account {
2426
accounts, err := mc.ListAccounts(context.Background(), moov.WithAccountName("Lincoln National Corporation"))

pkg/moov/card_issuing_api.go

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
package moov
2+
3+
import (
4+
"context"
5+
"net/http"
6+
)
7+
8+
// CreateIssuedCard requests a new card be issued for the given account
9+
// https://docs.moov.io/api/money-movement/issuing/create/
10+
func (c Client) CreateIssuedCard(ctx context.Context, accountID string, card CreateIssuedCard) (*IssuedCard, error) {
11+
httpResp, err := c.CallHttp(ctx,
12+
Endpoint(http.MethodPost, pathIssuedCards, accountID),
13+
AcceptJson(),
14+
JsonBody(card))
15+
if err != nil {
16+
return nil, err
17+
}
18+
19+
return CompletedObjectOrError[IssuedCard](httpResp)
20+
}
21+
22+
// ListIssuedCards retrieves all issued cards for the given account
23+
// https://docs.moov.io/api/money-movement/issuing/list/
24+
func (c Client) ListIssuedCards(ctx context.Context, accountID string, filters ...ListIssuedCardsFilter) ([]IssuedCard, error) {
25+
httpResp, err := c.CallHttp(ctx,
26+
Endpoint(http.MethodGet, pathIssuedCards, accountID),
27+
prependArgs(filters, AcceptJson())...)
28+
if err != nil {
29+
return nil, err
30+
}
31+
32+
return CompletedListOrError[IssuedCard](httpResp)
33+
}
34+
35+
// GetIssuedCard retrieves the specified issued card for the given account
36+
// https://docs.moov.io/api/money-movement/issuing/get/
37+
func (c Client) GetIssuedCard(ctx context.Context, accountID string, cardID string) (*IssuedCard, error) {
38+
httpResp, err := c.CallHttp(ctx,
39+
Endpoint(http.MethodGet, pathIssuedCard, accountID, cardID),
40+
AcceptJson())
41+
if err != nil {
42+
return nil, err
43+
}
44+
45+
return CompletedObjectOrError[IssuedCard](httpResp)
46+
}
47+
48+
// UpdateIssuedCard updates a specified issued card for the given account
49+
// https://docs.moov.io/api/money-movement/issuing/update/
50+
func (c Client) UpdateIssuedCard(ctx context.Context, accountID string, cardID string, update UpdateIssuedCard) error {
51+
httpResp, err := c.CallHttp(ctx,
52+
Endpoint(http.MethodPatch, pathIssuedCard, accountID, cardID),
53+
AcceptJson(),
54+
JsonBody(update))
55+
if err != nil {
56+
return err
57+
}
58+
59+
return CompletedNilOrError(httpResp)
60+
}
61+
62+
// ListIssuedCardAuthorizations retrieves all issued card authorizations for the given account
63+
// https://docs.moov.io/api/money-movement/issuing/list-authorizations/
64+
func (c Client) ListIssuedCardAuthorizations(ctx context.Context, accountID string, filters ...ListIssuedCardAuthorizationsFilter) ([]IssuedCardAuthorization, error) {
65+
httpResp, err := c.CallHttp(ctx,
66+
Endpoint(http.MethodGet, pathIssuingAuthorizations, accountID),
67+
prependArgs(filters, AcceptJson())...)
68+
if err != nil {
69+
return nil, err
70+
}
71+
72+
return CompletedListOrError[IssuedCardAuthorization](httpResp)
73+
}
74+
75+
// GetIssuedCardAuthorization retrieves the details of an issued card authorization for the given account
76+
// https://docs.moov.io/api/money-movement/issuing/get-authorization/
77+
func (c Client) GetIssuedCardAuthorization(ctx context.Context, accountID string, authorizationID string) (*IssuedCardAuthorization, error) {
78+
httpResp, err := c.CallHttp(ctx,
79+
Endpoint(http.MethodGet, pathIssuingAuthorization, accountID, authorizationID),
80+
AcceptJson())
81+
if err != nil {
82+
return nil, err
83+
}
84+
85+
return CompletedObjectOrError[IssuedCardAuthorization](httpResp)
86+
}
87+
88+
// ListIssuedCardAuthorizationEvents retrieves all events that affect an issued card authorization for the given account
89+
// https://docs.moov.io/api/money-movement/issuing/list-authorization-events/
90+
func (c Client) ListIssuedCardAuthorizationEvents(ctx context.Context, accountID string, authorizationID string, filters ...ListIssuedCardAuthorizationEventsFilter) ([]IssuedCardAuthorizationEvent, error) {
91+
httpResp, err := c.CallHttp(ctx,
92+
Endpoint(http.MethodGet, pathIssuingAuthorizationEvents, accountID, authorizationID),
93+
prependArgs(filters, AcceptJson())...)
94+
if err != nil {
95+
return nil, err
96+
}
97+
98+
return CompletedListOrError[IssuedCardAuthorizationEvent](httpResp)
99+
}
100+
101+
// ListIssuedCardAuthorizations retrieves all issued card transactions for the given account
102+
// https://docs.moov.io/api/money-movement/issuing/list-card-transactions/
103+
func (c Client) ListIssuedCardTransactions(ctx context.Context, accountID string, filters ...ListIssuedCardTransactionsFilter) ([]IssuedCardTransaction, error) {
104+
httpResp, err := c.CallHttp(ctx,
105+
Endpoint(http.MethodGet, pathIssuingTransactions, accountID),
106+
prependArgs(filters, AcceptJson())...)
107+
if err != nil {
108+
return nil, err
109+
}
110+
111+
return CompletedListOrError[IssuedCardTransaction](httpResp)
112+
}
113+
114+
// GetIssuedCardAuthorization retrieves the details of an issued card transaction for the given account
115+
// https://docs.moov.io/api/money-movement/issuing/get-card-transaction/
116+
func (c Client) GetIssuedCardTransaction(ctx context.Context, accountID string, cardTransactionID string) (*IssuedCardTransaction, error) {
117+
httpResp, err := c.CallHttp(ctx,
118+
Endpoint(http.MethodGet, pathIssuingTransaction, accountID, cardTransactionID),
119+
AcceptJson())
120+
if err != nil {
121+
return nil, err
122+
}
123+
124+
return CompletedObjectOrError[IssuedCardTransaction](httpResp)
125+
}

0 commit comments

Comments
 (0)