Search code examples
c#.netangularpayment-gateway

Request to URL from Angular To payfast payment vendor


I need to perform a form POST to a 3rd party payment provider with Angular The flow need to be as follows.

The payment gateway I'm using is PayFast.

The problem is that in some cases when I perform URL redirect successfully I don't receive any response from payment gateway. When a user clicks "Pay". he is redirected to the success page http://example.com/success and in case of error response to page http://example.com/cancel.

HttpClient through service

I've also tried making HttpClient POST request inside the Angular app and without NodeJS backend. In that case, I call the Payment Gateway URL directly but with CORS error.

payment.service.ts:

payFunction(parameters: any){
  return this._httpClient.post('https://test-wallet.example.com/checkout/'+ 
      'param1='+parameters.param1+ 
      '&param2='+parameters.param2+
      '&param3='+parameters.param3+ 
      '&param4='+parameters.param4+ 
      '&param5='+parameters.param5+
      '&param6='+parameters.param6+ 
      '&param7='+parameters.param7+
      '&param8='+parameters.param8+
      '&param9='+parameters.param9
      ,parameters
      ,this.httpOptions 
    )
   .catch(err => {
      console.log(err);
      return Observable.of(err)
   })
}

I call the previous service in component:

async test(form){
  await this._myPaymentService.payFunction(form.value).subscribe(res => {
        console.log(res);
})

But here I'm getting cors policy error if I even go with allow header with cross origin to * then it will not work with production modes

Next method I used is Form Post method as shown below.

<form [action]="'https://test-wallet.example.com/checkout/'" ngNoForm method="POST" target="_blank">
  <button type="submit">Pay with card</button>
  <input name='param1' value='param1'>
  <input name='param2' value='param2'>
  <input name='param3' value='param3'>
  <input name='param4' value='param4'>
  <input name='param5' value='param5'>
  <input name='param6' value='param6'>
  <input name='param7' value='param7'>
  <input name='param8' value='param8'>
  <input name='param9' value='param9'>
**But no way to catch the response back from that.**

Can any one please help me out for how to make it out in backend .NET Core API and send the response back to the front end based on which I can show a message to user.


Solution

  • When you need make a post to an URL that show a page you need use a form with ngNoForm and use javascript to "submit" the form.

    e.g. imagine you have a form like

    <!--see the "ngNoForm" and the "id"-->
    <form ngNoForm id="paymentForm" action="https://external-url" method="POST">
      <!--see that all the inputs are hidden
          and we binding [value] to a variable in .ts-->
      <input type="hidden" name="param1" [value]="param1"/>
      <input type="hidden" name="param2" [value]="param1"/>
    </form>
    

    In a function we can

    sendDataToExternalUrl()
    {
       //we get the Form
       const form=document.getElementById('paymentForm') as HTMLFormElement
       if (form)
          form.submit()
    }
    

    You can use also a template reference variable and ViewChild

    <form ngNoForm #paymentForm action="https://external-url" ... >
       ...
    </form>
    

    And use

    @ViewChild("paymentForm",{static:true}) form:ElementRef
    
    sendDataToExternalUrl()
    {
       //we get the Form
       const form=this.form.nativeElement as HTMLFormElement
       if (form)
          form.submit()
    }
    

    NOTE: In general in all the "payments integration" you have three "urls" that generally you pass as parameter in the form (sometimes, some payments integration the 3rd (urlNotifify and fixed and is added in the config of the payment)

    1. urlOK: where the form of external page goes when the user click Ok and the payment is sucesfully, e.g. http://yourdominio.com/paymentOk
    2. urlCancel: where the form of external page goes when the user click Cancel,, e.g. http://yourdominio.com/paymentCancel
    3. urlNotify: the API where you get the response of the payment (can be positive or negative) and is where you update the database e.g. http://yourdominio.com/api/paymentCancel <--see that it's an api, not the Angular application

    NOTE2: Check if you're sending all the necessary parameters.

    NOTE3: if you give value to the variables in .ts use a setTimeout before submit or you send the data "empty"

    sendDataToExternalUrl()
    {
       //we get the Form
       const form=document.getElementById('paymentForm') as HTMLFormElement
       if (form)
       {
          this.param1=34.5
          this.param2="New order"
          setTimeout(()=>{
             form.submit()
          })
    }