Skip to content

Commit b2fb1f1

Browse files
authored
Credit Accounts and Cards (#303)
* added CreditAccount updated DepositAccount added test for CreditAccountDTO * added CreditAccountRequests * added Credit Cards and small changes * filter by type * added credit cards * update some create card attributes * change Pick to Omit * CreditAccountCloseReason * bin type is a string * typo
1 parent 2177a3d commit b2fb1f1

File tree

10 files changed

+524
-146
lines changed

10 files changed

+524
-146
lines changed

helpers.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { AddAuthorizedUsersRequest, CloseAccountRequest, CloseReason, MobileWalletPayloadRequest, RemoveAuthorizedUsersRequest } from "./types"
1+
import { AddAuthorizedUsersRequest, CloseAccountRequest, CloseAccountType, CloseReason, MobileWalletPayloadRequest, RemoveAuthorizedUsersRequest } from "./types"
22
import { State, Address, FullName, Phone, Status, Title, Officer, BeneficialOwner, BusinessContact, AuthorizedUser, Counterparty, Coordinates, UsAddress, InternationalAddress, Relationship, RelationshipsArrayData } from "./types/common"
33
export function createUsAddress(street: string, street2: string | null, city: string, state: State | null, postalCode: string, country: "US"): UsAddress {
44
return {
@@ -157,11 +157,11 @@ export function createMobileWalletRequest(cardId: string, signedNonce: string):
157157
}
158158
}
159159

160-
export function createCloseAccountRequest(accountId: string, closeReason: CloseReason = "ByCustomer" ): CloseAccountRequest {
160+
export function createCloseAccountRequest(accountId: string, closeReason: CloseReason = "ByCustomer", accountType: CloseAccountType = "depositAccountClose"): CloseAccountRequest {
161161
return {
162162
accountId: accountId,
163163
data: {
164-
type: "accountClose",
164+
type: accountType,
165165
attributes: {
166166
reason: closeReason
167167
}

resources/account.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export class Accounts extends BaseResource {
5656
...(params?.include && {"include": params.include}),
5757
...(params?.fromBalance && {"filter[fromBalance]": params.fromBalance}),
5858
...(params?.toBalance && {"filter[toBalance]": params.toBalance}),
59+
...(params?.type && {"filter[type]": params.type})
5960
}
6061

6162
if (params?.status)
@@ -133,4 +134,8 @@ export interface AccountListParams extends BaseListParams {
133134
*/
134135
toBalance?: number
135136

137+
/**
138+
* Optional. Filters Accounts by type. Valid values are deposit or credit.
139+
*/
140+
type?: string
136141
}

resources/baseResource.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ export class BaseResource {
7575
.catch(error => { throw extractUnitError(error) })
7676
}
7777

78+
protected async httpPostResourcePath<T>(data?: DataPayload | { data: object; }, config?: { headers?: object; params?: object; }): Promise<T> {
79+
return this.httpPost("", data, config)
80+
}
81+
82+
7883
protected async httpPostFullPath<T>(path: string, data?: DataPayload | { data: object; }, config?: { headers?: object; params?: object; }): Promise<T> {
7984
const conf = {
8085
headers: this.mergeHeaders(config?.headers),

resources/cards.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
import {
2-
Card, CardLimits, CreateDebitCardRequest, EnableCardToCardPaymentRequest, EnableCardToCardPaymentResponse, MobileWalletPayload, MobileWalletPayloadRequest, PinStatus, ReplaceCardRequest, UpdateCardRequest
3-
} from "../types/cards"
2+
Card, CardLimits, CreateDebitCardRequest, EnableCardToCardPaymentRequest, EnableCardToCardPaymentResponse, MobileWalletPayload, MobileWalletPayloadRequest, PinStatus, ReplaceCardRequest, UpdateCardRequest, CreateCardRquest} from "../types/cards"
43
import { BaseListParams, Include, UnitConfig, UnitResponse } from "../types/common"
54
import { Customer } from "../types/customer"
65
import { Account } from "../types/account"
76
import { BaseResource } from "./baseResource"
87

98
export class Cards extends BaseResource {
10-
119
securePath = "https://secure.api.s.unit.sh"
1210

1311
constructor(token: string, basePath: string, config?: UnitConfig) {
@@ -20,6 +18,10 @@ export class Cards extends BaseResource {
2018
return await this.httpPost<UnitResponse<Card>>("", { data: request })
2119
}
2220

21+
public async create(request: CreateCardRquest): Promise<UnitResponse<Card>> {
22+
return await this.httpPostResourcePath<UnitResponse<Card>>({ data: request })
23+
}
24+
2325
public async reportStolen(id: string): Promise<UnitResponse<Card>> {
2426
const path = `/${id}/report-stolen`
2527
return await this.httpPost<UnitResponse<Card>>(path)

tests/accounts.spec.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,5 +81,4 @@ describe("Close Account", () => {
8181
expect(account.type).toBe("depositAccount")
8282
expect(closedAccount.attributes.status).toBe("Closed")
8383
})
84-
})
85-
84+
})

tests/credits.spec.ts

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
import { CreateBusinessCreditCardRequest, CreateBusinessVirtualCreditCardRequest, Unit } from "../unit"
2+
import { CloseAccountRequest, CreditAccount } from "../types/account"
3+
4+
import dotenv from "dotenv"
5+
import { createCreditAccount } from "./testHelpers"
6+
import { createAddress, createFullName, createPhone } from "../helpers"
7+
dotenv.config()
8+
const unit = new Unit(process.env.UNIT_TOKEN || "test", process.env.UNIT_API_URL || "test")
9+
const accountsId: string[] = []
10+
11+
async function createAccount() {
12+
const res = await createCreditAccount(unit)
13+
const account = await unit.accounts.get(res.data.id)
14+
expect(account.data.type).toBe("creditAccount")
15+
return account.data.id
16+
}
17+
18+
async function closeAccount(accountId: string) {
19+
const req: CloseAccountRequest = {
20+
accountId,
21+
data: {
22+
type: "creditAccountClose",
23+
attributes: {
24+
reason: "Overdue"
25+
}
26+
}
27+
}
28+
29+
const res = await unit.accounts.closeAccount(req)
30+
expect(res.data.type).toBe("creditAccount")
31+
return res
32+
}
33+
34+
describe("Credit Accounts List", () => {
35+
let accountId = ""
36+
37+
beforeAll(async () => {
38+
accountId = await createAccount()
39+
})
40+
41+
afterAll(async () => {
42+
await closeAccount(accountId)
43+
})
44+
45+
test("Get Credit Accounts List", async () => {
46+
const res = await unit.accounts.list({type: "credit"})
47+
res.data.forEach(element => {
48+
expect(element.type).toBe("creditAccount")
49+
accountsId.push(element.id)
50+
})
51+
52+
accountsId.forEach(async id => {
53+
const res = await unit.accounts.get(id)
54+
expect(res.data.type).toBe("creditAccount")
55+
})
56+
})
57+
58+
test("Get accounts list with included customer", async () => {
59+
accountsId.forEach(async id => {
60+
const res = await unit.accounts.get(id, "customer")
61+
expect(res.included && res.included.length > 0).toBeTruthy()
62+
})
63+
})
64+
})
65+
66+
describe("Create Account", () => {
67+
test("Create Credit Account", async () => {
68+
const accountId = await createAccount()
69+
const res = await closeAccount(accountId)
70+
expect(res.data.id).toBe(accountId)
71+
72+
})
73+
})
74+
75+
describe("Test DTO structure", () => {
76+
test("Test Credit Account DTO", () => {
77+
const creditAccount: CreditAccount = {
78+
"type": "creditAccount",
79+
"id": "42",
80+
"attributes": {
81+
"createdAt": "2000-05-11T10:19:30.409Z",
82+
"name": "Peter Parker",
83+
"status": "Open",
84+
"creditTerms": "credit_terms_1",
85+
"currency": "USD",
86+
"balance": 10000,
87+
"hold": 0,
88+
"available": 10000,
89+
"tags": {
90+
"purpose": "some_purpose"
91+
},
92+
"creditLimit": 200000
93+
},
94+
"relationships": {
95+
"customer": {
96+
"data": {
97+
"type": "customer",
98+
"id": "45555"
99+
}
100+
},
101+
"org": {
102+
"data": {
103+
"type": "org",
104+
"id": "1"
105+
}
106+
}
107+
}
108+
}
109+
110+
expect(creditAccount.type).toBe("creditAccount")
111+
})
112+
})
113+
114+
describe("Credit Credit Card", () => {
115+
test("Create Business Credit Card", async () => {
116+
const accountId = await createAccount()
117+
118+
const req: CreateBusinessCreditCardRequest = {
119+
type: "businessCreditCard",
120+
attributes: {
121+
fullName: createFullName("Richard", "Hendricks"),
122+
ssn: "123456789",
123+
address: createAddress("5230 Newell Rd", null, "Palo Alto", "CA", "94303", "US"),
124+
shippingAddress: createAddress("5230 Newell Rd", null, "Palo Alto", "CA", "94303", "US"),
125+
dateOfBirth: "2001-08-10",
126+
127+
phone: createPhone("1", "5555555555")
128+
},
129+
relationships: {
130+
account: {
131+
data: {
132+
type: "creditAccount",
133+
id: accountId
134+
}
135+
}
136+
}
137+
}
138+
139+
const res = await unit.cards.create(req)
140+
expect(res.data.type).toBe("businessCreditCard")
141+
142+
const closeRes = await unit.cards.closeCard(res.data.id)
143+
expect(closeRes.data.id).toBe(res.data.id)
144+
})
145+
146+
test("Create Business Virtual Credit Card", async () => {
147+
const accountId = await createAccount()
148+
149+
const req: CreateBusinessVirtualCreditCardRequest = {
150+
type: "businessVirtualCreditCard",
151+
attributes: {
152+
fullName: createFullName("Richard", "Hendricks"),
153+
ssn: "123456789",
154+
address: createAddress("5230 Newell Rd", null, "Palo Alto", "CA", "94303", "US"),
155+
dateOfBirth: "2001-08-10",
156+
157+
phone: createPhone("1", "5555555555")
158+
},
159+
relationships: {
160+
account: {
161+
data: {
162+
type: "creditAccount",
163+
id: accountId
164+
}
165+
}
166+
}
167+
}
168+
169+
const res = await unit.cards.create(req)
170+
expect(res.data.type).toBe("businessVirtualCreditCard")
171+
172+
const closeRes = await unit.cards.closeCard(res.data.id)
173+
expect(closeRes.data.id).toBe(res.data.id)
174+
})
175+
})
176+

tests/testHelpers.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { createFullName, createAddress, createPhone, createOfficer, createBusinessContact, createBeneficialOwner } from "../helpers"
2-
import { CreateBusinessApplicationRequest, CreateDepositAccountRequest, CreateIndividualApplicationRequest, CreateTrustApplicationRequest, Unit, VerifyDocumentRequest } from "../unit"
2+
import { CreateBusinessApplicationRequest, CreateCreditAccountRequest, CreateDepositAccountRequest, CreateIndividualApplicationRequest, CreateTrustApplicationRequest, Unit, VerifyDocumentRequest } from "../unit"
33

44
export function createIndividualApplication(unit: Unit) {
55
const createIndividualApplication: CreateIndividualApplicationRequest = {
@@ -171,6 +171,31 @@ export async function createBussinessAccount(unit: Unit) {
171171
return createAccount(customerId ? customerId : "", unit)
172172
}
173173

174+
export async function createCreditAccount(unit: Unit) {
175+
const customerId = await createBusinessCustomer(unit)
176+
177+
const createDepositAccountRequest: CreateCreditAccountRequest = {
178+
type: "creditAccount",
179+
attributes: {
180+
creditTerms: "credit_terms_test",
181+
creditLimit: 2000,
182+
tags: {
183+
purpose: "test_credit_account"
184+
}
185+
},
186+
relationships: {
187+
customer: {
188+
data: {
189+
type: "customer",
190+
id: customerId
191+
}
192+
}
193+
}
194+
}
195+
196+
return unit.accounts.create(createDepositAccountRequest)
197+
}
198+
174199
export function createVerifyDocumentRequest(applicationId: string, documentId: string, jobId: string): VerifyDocumentRequest {
175200
return { applicationId, documentId, data: { type: "selfieVerification", attributes: { jobId } } }
176201
}

0 commit comments

Comments
 (0)