-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathnestjs-service.ts
More file actions
88 lines (78 loc) · 2.58 KB
/
Copy pathnestjs-service.ts
File metadata and controls
88 lines (78 loc) · 2.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/**
* NestJS integration example for satim-node.
*
* Drop SatimModule into your AppModule and inject SatimService
* wherever you need to process payments.
*/
import {
Injectable,
Module,
BadRequestException,
ServiceUnavailableException,
} from '@nestjs/common';
import {
Satim,
SatimApiError,
SatimNetworkError,
DZDToCentimes,
OrderStatusResponse,
} from 'satim-node-sdk';
// ─── Service ──────────────────────────────────────────────────────────────────
@Injectable()
export class SatimService {
private readonly satim: Satim;
constructor() {
this.satim = new Satim({
username: process.env.SATIM_USERNAME ?? '',
password: process.env.SATIM_PASSWORD ?? '',
terminalId: process.env.SATIM_TERMINAL ?? '',
sandbox: process.env.NODE_ENV !== 'production',
});
}
async initiatePayment(
orderNumber: string,
amountDZD: number
): Promise<{ orderId: string; formUrl: string }> {
try {
return await this.satim.registerOrder({
orderNumber,
amount: DZDToCentimes(amountDZD),
returnUrl: `${process.env.APP_URL}/payment/callback`,
failUrl: `${process.env.APP_URL}/payment/fail`,
description: `Order ${orderNumber}`,
});
} catch (err) {
this.handleError(err);
}
}
async verifyPayment(orderId: string): Promise<{ success: boolean; status: OrderStatusResponse }> {
try {
const status = await this.satim.getOrderStatus({ orderId });
return { success: this.satim.isPaymentSuccessful(status), status };
} catch (err) {
this.handleError(err);
}
}
async refund(orderId: string, amountDZD: number): Promise<{ success: boolean }> {
try {
return await this.satim.refundOrder({ orderId, amount: DZDToCentimes(amountDZD) });
} catch (err) {
this.handleError(err);
}
}
private handleError(err: unknown): never {
if (err instanceof SatimApiError) {
throw new BadRequestException(`SATIM: ${err.errorMessage} (code ${err.errorCode})`);
}
if (err instanceof SatimNetworkError) {
throw new ServiceUnavailableException('Payment gateway unreachable');
}
throw err;
}
}
// ─── Module ───────────────────────────────────────────────────────────────────
@Module({
providers: [SatimService],
exports: [SatimService],
})
export class SatimModule {}