You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ionic 3集成PayFort(重定向模式)HTTP POST请求技术问询

在Ionic中通过重定向模式集成PayFort(无SDK方案)

Got it, integrating PayFort in Ionic without an SDK using redirect mode is totally doable—let's walk through the correct approach since your current code might hit some snags with content type and user experience. Here's how to make it work smoothly:

1. Key Fixes & Background

First off, PayFort's payment page endpoint expects application/x-www-form-urlencoded request data, not JSON. Your current JSON.stringify approach will cause the request to fail because the server can't parse the payload correctly. Also, we need to render the actual PayFort payment page in an in-app browser so users can enter their card details—direct HttpClient calls won't show the UI.

2. Full Implementation Code

We'll use @ionic-native/in-app-browser to handle the payment flow, since it lets us load external pages and listen for redirects. Here's a complete service example:

import { HttpClient } from '@angular/common/http';
import { InAppBrowser } from '@ionic-native/in-app-browser/ngx';
import { Injectable } from '@angular/core';
import * as CryptoJS from 'crypto-js'; // For signature generation/verification

@Injectable({
  providedIn: 'root'
})
export class PayFortPaymentService {
  // Use sandbox URL for testing, switch to production when ready
  private payFortBaseUrl = 'https://sbpayments.payfort.com/FortAPI/paymentPage';
  private merchantSecret = 'YOUR_MERCHANT_SECRET'; // Store this securely!

  constructor(
    private http: HttpClient,
    private iab: InAppBrowser
  ) { }

  startPayment() {
    // Generate a unique merchant reference (use your own logic here)
    const merchantRef = `ORD-${Date.now()}`;

    // Build your payment parameters as per PayFort docs
    const paymentParams = {
      access_code: 'YOUR_ACCESS_CODE',
      amount: '10000', // Remember: this is the smallest currency unit (SAR 100 = 10000)
      command: 'AUTHORIZATION',
      currency: 'SAR',
      customer_email: 'test@payfort.com',
      language: 'en',
      merchant_identifier: 'YOUR_MERCHANT_ID',
      merchant_reference: merchantRef,
      payment_option: 'MASTERCARD',
      return_url: 'https://your-app-domain.com/payment-result', // Set this in your PayFort dashboard
      signature: this.generateRequestSignature(paymentParams)
    };

    // Open a blank in-app browser window
    const paymentBrowser = this.iab.create('_blank', '_self', { location: 'yes' });

    // When the blank page loads, inject an auto-submitting form to PayFort
    paymentBrowser.on('loadstop').subscribe(event => {
      if (event.url === 'about:blank') {
        const autoSubmitForm = `
          <form id="payfort-payment-form" action="${this.payFortBaseUrl}" method="POST">
            ${Object.keys(paymentParams).map(key => 
              `<input type="hidden" name="${key}" value="${paymentParams[key]}">`
            ).join('')}
          </form>
          <script>document.getElementById('payfort-payment-form').submit();</script>
        `;
        paymentBrowser.executeScript({ code: `document.body.innerHTML = \`${autoSubmitForm}\`` });
      }
    });

    // Listen for the redirect to your return_url to handle payment results
    paymentBrowser.on('loadstart').subscribe(event => {
      if (event.url.includes(this.getReturnUrlHost())) {
        // Parse the callback parameters from the URL
        const urlParams = new URLSearchParams(event.url.split('?')[1]);
        const paymentResult = Object.fromEntries(urlParams.entries());

        // Verify the signature to ensure the response isn't tampered with
        if (this.verifyCallbackSignature(paymentResult)) {
          switch (paymentResult.status) {
            case '14': // Authorization success (check PayFort docs for all status codes)
              console.log('Payment authorized successfully!', paymentResult);
              // Add your success logic here (update order status, show toast, etc.)
              break;
            default:
              console.log('Payment failed:', paymentResult.response_message);
              // Add your failure logic here
              break;
          }
        } else {
          console.log('Warning: Payment signature verification failed!');
        }

        paymentBrowser.close();
      }
    });

    // Handle errors or user closing the browser
    paymentBrowser.on('exit').subscribe(() => {
      console.log('Payment flow cancelled by user');
    });
  }

  // Generate PayFort request signature per official docs
  private generateRequestSignature(params: Record<string, string>): string {
    // Sort parameters alphabetically
    const sortedKeys = Object.keys(params).sort();
    let signatureString = '';

    sortedKeys.forEach(key => {
      signatureString += `${key}=${params[key]}&`;
    });
    // Append your merchant secret passphrase
    signatureString += `sha_request_passphrase=${this.merchantSecret}`;

    // Return SHA-256 hex hash
    return CryptoJS.SHA256(signatureString).toString(CryptoJS.enc.Hex);
  }

  // Verify the callback signature from PayFort
  private verifyCallbackSignature(params: Record<string, string>): boolean {
    const incomingSignature = params.signature;
    delete params.signature; // Remove signature from the params we process

    const sortedKeys = Object.keys(params).sort();
    let signatureString = '';

    sortedKeys.forEach(key => {
      signatureString += `${key}=${params[key]}&`;
    });
    signatureString += `sha_response_passphrase=${this.merchantSecret}`;

    const generatedSignature = CryptoJS.SHA256(signatureString).toString(CryptoJS.enc.Hex);
    return generatedSignature === incomingSignature;
  }

  // Helper to extract return URL host for callback detection
  private getReturnUrlHost(): string {
    const url = new URL('https://your-app-domain.com/payment-result');
    return url.host;
  }
}

3. Critical Setup Steps

  • Install Dependencies: Run npm install @ionic-native/in-app-browser crypto-js and add InAppBrowser to your app.module.ts providers array.
  • PayFort Dashboard Config: Make sure your return_url is registered in your PayFort merchant dashboard, and use the correct access code/merchant ID for your environment (sandbox vs production).
  • Secure Secret Storage: Never hardcode your merchant secret in client-side code! Use environment variables or a secure backend endpoint to generate signatures instead (client-side signature generation is shown here for demo purposes only).

4. Key Notes

  • Amount Format: Always use the smallest currency unit (e.g., SAR 1 = 100, AED 5 = 500) as specified in PayFort's docs.
  • Unique Merchant References: Ensure merchant_reference is unique for each transaction to avoid duplicate payments.
  • Status Codes: Refer to PayFort's official documentation for all possible status values—don't rely on just the example code's '14' status.

内容的提问来源于stack exchange,提问作者Aqib Bangash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:01:52