Impelient Bank Mellat Payment Gateway in Nestjs
Simple Code of node.js
مستندات پیاده سازی بانک ملت
Initial Payment


mellat.type.ts
javascript
export const MellatConfiguration = {
GatewayAddress: 'https://bpm.shaparak.ir/pgwchannel/payment.mellat?RefId=', WsdlInitial:
'https://bpm.shaparak.ir/pgwchannel/services/pgw?wsdl', WsdlConfirm:
'https://bpm.shaparak.ir/pgwchannel/services/pgw?wsdl',
};payment.controller.ts
typescript
@Post('/mellat/openTransaction') @UseGuards(CustomerGuard) @ApiOkResponse({
type: () => CreatePaymentMellatResultDto
}) @ApiBearerAuth() createMellat(@Body() createPaymentDto: CreatePaymentMellatDto, @Req() req: {
user: Partial<User>
},) {
return this.paymentMellatService.openTransaction(createPaymentDto, req.user,);
}Soap Initial Mellat payment
typescript
return await new Promise<any>((resolve, reject) => {
soap.createClient(
MellatConfiguration.WsdlInitial,
options,
function (err: any, client: any) {
if (err) {
console.error("Error creating SOAP client:", err);
reject(err);
}
client.bpPayRequest(requestData, (err, result) => {
if (err) {
console.error("Error making SOAP request:", err);
reject(err);
}
resolve(result);
});
},
);
});payment.mellat.service.ts
typescript
import {
Injectable, InternalServerErrorException
}
from '@nestjs/common';
import {
Payment, PaymentGateway, PaymentStatus,
}
from './entities/payment.entity';
import {
Model
}
from 'mongoose';
import {
InjectModel
}
from '@nestjs/mongoose';
import {
CreatePaymentMellatDto
}
from './dto/create.mellat.dto';
import {
User
}
from 'src/users/schemas/user.schema';
import configuration from 'src/config/configuration';
import {
MellatConfiguration
}
from './entities/mellat.type';
const soap = require('soap');
const moment = require('moment');
@Injectable()
export class PaymentMellatService {
constructor(@InjectModel(Payment.name) private paymentModel: Model<Payment>,) {
}
async openTransaction(createPaymentDto: CreatePaymentMellatDto, user: Partial<User>,) {
let token = '';
const localDate = moment().format('YYYYMMDD');
const localTime = moment().format('HHmmss');
// Make a SOAP request
const requestData = {
terminalId: configuration().mellat.terminalId, userName: configuration().mellat.username,
userPassword: configuration().mellat.userPassword, orderId: createPaymentDto.uniqueID, amount:
createPaymentDto.amount, localDate: localDate, localTime: localTime, additionalData:
createPaymentDto.additionalData, callBackUrl: configuration().mellat.callBackUrl, payerId: 0,
mobileNo: user.phoneNumber,
};
try {
const resolve = await this.SendRequestInitial(requestData);
if (!resolve.hasOwnProperty('return')) {
console.log('Return not found');
throw new InternalServerErrorException('Return not found');
}
const str = resolve.return;
const mySplit = str.split(',');
if (mySplit[0] != '0') {
console.log(mySplit[0]);
throw new InternalServerErrorException(mySplit[0]);
}
token = mySplit[1];
await this.paymentModel.create({
user: user, amount: createPaymentDto.amount, uniqueID: createPaymentDto.uniqueID, status:
PaymentStatus.Initial, gateway: PaymentGateway.Mellat, authority_code: token, authority:
resolve,
});
}
catch (error) {
console.log(error);
throw new InternalServerErrorException();
}
return {
paymentLink: MellatConfiguration.GatewayAddress + token, token: token,
};
}
async SendRequestInitial(requestData: any): Promise<any> {
moment.locale('en');
const options = {
overrideRootElement: {
namespace: 'ns1',
},
};
return await new Promise<any>((resolve, reject) => {
soap.createClient(MellatConfiguration.WsdlInitial, options, function (err: any, client: any) {
if (err) {
console.error('Error creating SOAP client:', err);
reject(err);
}
client.bpPayRequest(requestData, (err, result) => {
if (err) {
console.error('Error making SOAP request:', err);
reject(err);
}
resolve(result);
});
},);
});
}
}configuration.ts
typescript
mellat: { callBackUrl: process.env.MELLAT_CALLBACK_URL, terminalId:
process.env.MELLAT_TERMINAL_ID, username: process.env.MELLAT_USERNAME, userPassword:
process.env.MELLAT_USER_PASSWORD, },Verify Transaction

After the initial transaction and gateway callback, verifying the transaction is mandatory.
