Impelient Bank Mellat Payment Gateway in Nestjs

Simple Code of node.js

مستندات پیاده سازی بانک ملت

Initial Payment

Impelient Bank Mellat Payment Gateway in Nestjs
Impelient Bank Mellat Payment Gateway in Nestjs

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

Impelient Bank Mellat Payment Gateway in Nestjs

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