Skip to content

Commit ece0c97

Browse files
authored
Merge pull request fireayehu#18 from flavnat/feat/refund-verify
feat:add verify refund functionality
2 parents a13fb39 + a6a74e4 commit ece0c97

4 files changed

Lines changed: 78 additions & 1 deletion

File tree

src/chapa.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ import {
2525
InitializeResponse,
2626
RefundOptions,
2727
RefundResponse,
28+
VerifyRefundOptions,
29+
VerifyRefundResponse,
2830
TransferOptions,
2931
TransferResponse,
3032
VerifyOptions,
@@ -40,6 +42,7 @@ import {
4042
validateGetTransactionLogsOptions,
4143
validateInitializeOptions,
4244
validateRefundOptions,
45+
validateVerifyRefundOptions,
4346
validateTransferOptions,
4447
validateVerifyOptions,
4548
validateVerifyTransferOptions,
@@ -88,6 +91,10 @@ interface IChapa {
8891
signal?: AbortSignal
8992
): Promise<AuthorizeDirectChargeResponse>;
9093
refund(options: RefundOptions, signal?: AbortSignal): Promise<RefundResponse>;
94+
verifyRefund(
95+
options: VerifyRefundOptions,
96+
signal?: AbortSignal
97+
): Promise<VerifyRefundResponse>;
9198
verifyWebhook(payload: WebhookPayload | string, signature: string): boolean;
9299
}
93100

@@ -341,6 +348,20 @@ export class Chapa implements IChapa {
341348
});
342349
}
343350

351+
async verifyRefund(
352+
options: VerifyRefundOptions,
353+
signal?: AbortSignal
354+
): Promise<VerifyRefundResponse> {
355+
return withErrorHandling(async () => {
356+
validateVerifyRefundOptions(options);
357+
const response = await this.axiosInstance.get<VerifyRefundResponse>(
358+
`${ChapaUrls.REFUND}/${options.ref_id}/verify`,
359+
{ signal }
360+
);
361+
return response.data;
362+
});
363+
}
364+
344365
verifyWebhook(payload: WebhookPayload | string, signature: string): boolean {
345366
if (!this.webhookSecret) {
346367
throw new Error('Webhook secret not configured');

src/interfaces/refund.interface.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,13 @@ export interface RefundResponse {
1414
status: string;
1515
data: Record<string, unknown>;
1616
}
17+
18+
export interface VerifyRefundOptions {
19+
ref_id: string;
20+
}
21+
22+
export interface VerifyRefundResponse {
23+
message: string;
24+
status: string;
25+
data: Record<string, unknown>;
26+
}

src/validations/refund.validation.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { z } from 'zod';
2-
import { RefundOptions } from '../interfaces';
2+
import { RefundOptions, VerifyRefundOptions } from '../interfaces';
33

44
const refundSchema = z.object({
55
tx_ref: z.string(),
@@ -16,3 +16,11 @@ const refundSchema = z.object({
1616
export const validateRefundOptions = (options: RefundOptions) => {
1717
return refundSchema.parse(options);
1818
};
19+
20+
const verifyRefundSchema = z.object({
21+
ref_id: z.string(),
22+
});
23+
24+
export const validateVerifyRefundOptions = (options: VerifyRefundOptions) => {
25+
return verifyRefundSchema.parse(options);
26+
};

test/refund.test.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,41 @@ describe('Refund', () => {
8181
expect(body.toString()).toBe('');
8282
});
8383
});
84+
85+
describe('Verify Refund', () => {
86+
const mockGet = jest.fn();
87+
let chapa: Chapa;
88+
89+
beforeEach(() => {
90+
mockGet.mockReset();
91+
(axios.create as jest.Mock).mockReturnValue({ get: mockGet });
92+
chapa = new Chapa({ secretKey: 'test-secret-key' });
93+
});
94+
95+
it('should validate required ref_id', async () => {
96+
await expect(
97+
chapa.verifyRefund({} as any)
98+
).rejects.toThrow();
99+
expect(mockGet).not.toHaveBeenCalled();
100+
});
101+
102+
it('should call get method with correct url', async () => {
103+
const options = {
104+
ref_id: 'REF-1234',
105+
};
106+
const responseData = {
107+
message: 'ok',
108+
status: 'success',
109+
data: { amount: 100 },
110+
};
111+
mockGet.mockResolvedValue({ data: responseData });
112+
113+
const response = await chapa.verifyRefund(options);
114+
115+
expect(response).toEqual(responseData);
116+
expect(mockGet).toHaveBeenCalledTimes(1);
117+
const [url, config] = mockGet.mock.calls[0];
118+
expect(url).toBe('/refund/REF-1234/verify');
119+
expect(config.signal).toBeUndefined();
120+
});
121+
});

0 commit comments

Comments
 (0)