Integrasi PAYKU 2

by PayKu

14
Raw
const crypto = require('crypto');
const axios = require('axios');

class PayKuGateway {
  constructor(apiKey, secretKey, baseURL = "https://payku.my.id") {
    this.apiKey = apiKey;
    this.secretKey = secretKey;
    this.baseURL = baseURL;
  }

  generateSignature(payload) {
    const timestamp = Date.now().toString();
    const payloadWithTimestamp = { ...payload, timestamp };
    const sortedKeys = Object.keys(payloadWithTimestamp).sort();
    const stringToSign = sortedKeys.map(k => `${k}=${payloadWithTimestamp[k]}`).join('&');
    const signature = crypto.createHmac('sha256', this.secretKey).update(stringToSign).digest('hex');
    
    return { signature, timestamp };
  }
  // request qris 
  async createTransaction(transactionData) {
    const { signature, timestamp } = this.generateSignature(transactionData);

    try {
      const response = await axios.post(`${this.baseURL}/api/create-transaction`, transactionData, {
        headers: {
          'x-api-key': this.apiKey,
          'x-signature': signature,
          'x-timestamp': timestamp,
          'Content-Type': 'application/json'
        }
      });
      
      if (response.data && response.data.success) {
        return {
          success: true,
          data: response.data.data,
          message: response.data.message || 'Transaction created successfully'
        };
      } else {
        throw new Error(response.data?.message || 'Unknown error from API');
      }
      
    } catch (error) {
      return this.handleError(error, 'Create Transaction');
    }
  }
  // cek transaksi 
  async getTransactionStatus(transactionId) {
    const { signature, timestamp } = this.generateSignature({ transaction_id: transactionId });

    try {
      const response = await axios.get(`${this.baseURL}/api/transaction/${transactionId}`, {
        headers: {
          'x-api-key': this.apiKey,
          'x-signature': signature,
          'x-timestamp': timestamp,
          'Content-Type': 'application/json'
        }
      });

      if (response.data && response.data.success) {
        return {
          success: true,
          data: response.data.data,
          message: 'Transaction status retrieved successfully'
        };
      } else {
        throw new Error(response.data?.message || 'Failed to get transaction status');
      }

    } catch (error) {
      return this.handleError(error, 'Get Transaction Status');
    }
  }
  // cancel request
  async cancelTransaction(transactionId) {
    const { signature, timestamp } = this.generateSignature({ transaction_id: transactionId });

    try {
      const response = await axios.post(`${this.baseURL}/api/transaction/${transactionId}/cancel`, {}, {
        headers: {
          'x-api-key': this.apiKey,
          'x-signature': signature,
          'x-timestamp': timestamp,
          'Content-Type': 'application/json'
        }
      });

      if (response.data && response.data.success) {
        return {
          success: true,
          message: response.data.message || 'Transaction cancelled successfully'
        };
      } else {
        throw new Error(response.data?.message || 'Failed to cancel transaction');
      }

    } catch (error) {
      return this.handleError(error, 'Cancel Transaction');
    }
  }

  handleError(error, operation) {
    if (error.response) {
      const errorMsg = error.response.data?.message || error.response.statusText || 'API Error';
      return {
        success: false,
        error: `${operation} API Error [${error.response.status}]: ${errorMsg}`
      };
    } else if (error.request) {
      return {
        success: false,
        error: `${operation} Network Error: Unable to connect to payment gateway`
      };
    } else {
      return {
        success: false,
        error: `${operation} failed: ${error.message}`
      };
    }
  }
}

// ========== CONTOH PENGGUNAAN ==========

const main = async () => {
  const payku = new PayKuGateway(
    "PAYKU_1234567890", // API Key
    "11111aaaaa22222bbbbbb333333cccccccc" // Secret Key
  );

  try {
    const timestamp = Date.now().toString();
    // request qris
    const createResult = await payku.createTransaction({
      external_id: "SN" + timestamp,
      amount: 1000,
      description: "Test Payku Integration",
      customer_name: "Demo",
      customer_email: "demo@gmail.com",
      customer_phone: "08123456789",
      webhook_url: "https://payku.my.id/webhook"
    });

    if (!createResult.success) {
      console.error('❌ Create Transaction Error:', createResult.error);
      return;
    }
    const transactionId = createResult.data.transaction_id;
    // cek status
    const statusResult = await payku.getTransactionStatus(transactionId);
    if (statusResult.success) {
      if (statusResult.data.paid_at) {
      }
    } else {
      console.error('❌ Get Status Error:', statusResult.error);
    }
    // cancel request yg belum sukses
    if (statusResult.success && statusResult.data.status !== 'paid') {
      const cancelResult = await payku.cancelTransaction(transactionId);
      
      if (cancelResult.success) {
      } else {
        console.error('❌ Cancel Transaction Error:', cancelResult.error);
      }
    } else if (statusResult.success && statusResult.data.status === 'paid') {
      console.log('\n⚠️ Cannot cancel paid transaction');
    }

  } catch (error) {
    console.error('❌ Unexpected Error:', error.message);
  }
};

main();