Midtrans/midtrans-nodejs-client

menggunakan fungsi snap pay di component

mfebras opened this issue · 14 comments

  1. bagaimana cara import
    <script src="https://app.sandbox.midtrans.com/snap/snap.js" data-client-key="<Set your ClientKey here>"></script>
    di react js component?

  2. bagaimana menggunakan snap.pay('SNAP_TOKEN') di react js component?

Hi @mfebras
Library snap.js tidak spesifik di design untuk ReactJS.
Tapi in theory, selama ReactJS berjalan di frontend, seharusnya bisa digunakan bersamaan dengan snap.js.
Sebagai pengguna ReactJS, silahkan coba cari atau bertanya ke community ReactJS bagaimana cara menggunakan external JS library.

Seperti ini contoh jawaban issue sejenis, mungkin bisa dicoba:
facebook/create-react-app#3007 (comment)
Di comment tersebut berhasil menggunakan jquery.js dan component ReactJS

Thanks.

@rizdaprasetya
terima kasih atas penjelasannya

apakah akan ada penyesuaian atau library untuk React JS ?

mengingat jalan seperti ini memang bisa facebook/create-react-app#3007 (comment),
tetapi disisi lain, React JS tidak untuk itu

karena pernah saya tanyakan kepada beberapa teman yang sudah mendalami React JS,
"apakah bisa React JS dicampur dengan jquery?"
jawabnya : "Bisa. Bisa hancur. Memakai React JS itu berarti memakainya untuk pengganti library seperti jquery. Jika masih pakai jquery dan semacamnya ya mending pakai jquery."

semoga jadi pertimbangan

Hi @alfanzain kelihatannya Anda salah memahami. Bukan soal JQuery-nya tetapi yg bisa dicontoh dari link tersebut adalah metode agar bisa load 3rd party hosted library agar bisa digunakan di React.

Mengadopsi metode pada link tersebut, caranya untuk Snap:
put following line in your /public/index.html

<script src="https://app.sandbox.midtrans.com/snap/snap.js"></script>

use it in your project:

window.snap.pay('<snap-token>')

... "apakah bisa React JS dicampur dengan jquery?"
jawabnya : "Bisa. Bisa hancur. ...

Anda bisa tanyakan lebih lanjut ke teman Anda, apa yang dimaksud "hancur" dalam konteks tersebut. Itu karena JQuery & React memiliki fungsi yg saling overlap dalam hal HTML/UI manipulation framework, dan punya 2 paradigma yang saling berbeda. Walaupun demikian pun menurut saya "hancur" juga bukan kata yg tepat.

Sedangkan Snap.js sama sekali bukan untuk HTML/UI manipulation framework, dan tidak ada paradigma yg bertentangan dengan React. Jadi sample case yang anda berikan kurang relevan.

Terima kasih.

(Funfact: github.com sendiri mengimplementasikan sebagian React dan sebagian JQuery di page-page yang berbeda. Dan tidak terlihat seperti "hancur", tapi hal ini di luar topik diskusi)

Note: Keuntungan lain menggunakan Snap.js yg dihost di Midtrans adalah untuk memastikan faktor security dan akan otomatis mendapat versi paling update & secure.

@rizdaprasetya

apakah data-client-key di script tag HTML sesuatu yg mandatory krn saya lihat di DOCS terdapat key itu sedangkan di contoh yang Anda tulis tidak menggunakan itu

docs:
<script type="text/javascript" src="https://app.sandbox.midtrans.com/snap/snap.js" data-client-key="<CLIENT-KEY>"></script>

saya menanyakan hal ini, krn saya membutuhkan client-key yang dynamic tergantung suatu parameter yang dipilih di frontend

any suggestion are welcome. thank you

Hi @ryanadhi pertanyaan bagus. Attribute data-client-key di script tag snap.js tidak mandatory, sifatnya optional tetapi direkomendasikan.

Perbedaan dan konsekuensinya:

  • Jika memakai data-client-key: Konfigurasi yg bersifat frontend/client side (seperti Snap UI color-scheme, misalkan jika anda ingin ubah menjadi warna merah) akan dibaca dari Merchant Dashboard yang sudah anda setting di menu Snap Preference.
  • Jika tidak memakai data-client-key: Konfigurasi di atas tidak dibaca, (seperti akan menampilkan tampilan UI color-scheme default)

Jadi memang sebaiknya gunakan attribute tersebut.

Untuk cara supaya bisa dynamic script tag attribute value dalam konteks menggunakan ReactJS. Sebaiknya refer ke dokumentasi/community ReactJS karena caranya sangat beragam dan cepat berubah. Sebagai contoh saya gunakan salah satu cara yg direkomendasikan disini, yaitu metode useEffect hook:

useEffect(() => {
  const snapSrcUrl = 'https://app.sandbox.midtrans.com/snap/snap.js';
  const myMidtransClientKey = 'your-client-key-goes-here'; //change this according to your client-key

  const script = document.createElement('script');
  script.src = snapSrcUrl;
  script.setAttribute('data-client-key', myMidtransClientKey);
  script.async = true;

  document.body.appendChild(script);

  return () => {
    document.body.removeChild(script);
  }
}, []);

Silahkan dicoba

Terima kasih pertanyaan dan masukan teman-teman di sini, team Midtrans berencana untuk menambahkan info ini ke official dokumentasi midtrans agar pembaca lain dapat terbantu jika mengalami issue yang sama.

@rizdaprasetya

Terima kasih sudah bersedia menjawab. Dan maaf saya keep out of topic di thread ini. Namun saya hanya ketemu thread ini yang berhubungan dgn React

Saat mengikuti step di atas saya terkendala spt ini dan SNAP tidak terbuka, apakah ini krn saya masih coba di local dan terkena CORS?

Screenshot 2021-04-26 100948
Screenshot 2021-04-26 100742

di akhir saya baru sadar saya belum memasukan menjalankannya dengan token yg tersedia. Apakah ada saran bagaimana utk memasukkan Token-nya? dan bagaiaman utk menjalankan function yang biasa teserdia di Snap? seperti onClose

Hi @ryanadhibit

  • 2 console error merah tersebut bisa diignore: biasanya karena browser Anda ada AdBlocker extension, sehingga otomatis blocking library analytics dari Google yang tidak penting (tidak merusak functionality), dengan message net::ERR_BLOCKED_BY_CLIENT.
  • 1 console warn kuning tersebut bisa diignore: Dev Tools browser yang anda pakai mencoba untuk me-load js.map file yang biasanya digunakan untuk environment development, dan tidak tersedia di environment production. Tidak merusak functionality.
    Jadi screenshot di atas seharusnya aman untuk diignore.

bagaiaman utk menjalankan function yang biasa teserdia di Snap?

Setelah Snap JS diimport di HTML page menggunakan useEffect seperti dijelaskan di atas, window.snap akan available sebagai global variable, cara memakainya adalah pada JS implementation Anda bisa panggil:

window.snap.pay( snapToken, options )
window.snap.pay('66e4fa55-fdac-4ef9-91b5-733b97d1b862', {
  onSuccess: function(result){
    /* You may add your own implementation here */
    
  },
  onPending: function(result){
    /* You may add your own implementation here */
    
  },
  onError: function(result){
    /* You may add your own implementation here */
    
  },
  onClose: function(){
    /* You may add your own implementation here */
    
  }
})

ref: Snap JS callbacks docs

Untuk membuat snap.pay di client nodejs bagaimana yah kak?

hi @anggiatpangaribuan28 NodeJS biasanya digunakan sebagai backend. Jadi snap.js ataupun snap.pay tidak dipakai di backend. Tetapi di frontend.

Jika menggunakan NodeJS sebagai backend, silahkan pastikan frontendnya include HTML snippet sesuai dengan sample di docs berikut:
https://docs.midtrans.com/en/snap/integration-guide?id=_2-displaying-snap-payment-page-on-frontend

Atau silahkan dijelaskan lebih detail masalahnya. Atau provide sample frontend codenya. Thanks

i have problem error like here in React JS

Access to XMLHttpRequest at 'https://app.sandbox.midtrans.com/snap/v1/transactions' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

code :

..........
export default function Payment(props){

let snap = new midtransClient.Snap({
    // Set to true if you want Production Environment (accept real transaction).
    isProduction : false,
    serverKey : 'SB-Mid-server-SECRET'
});
let parameter = {
"transaction_details": {
    "order_id": "YOUR-ORDERID-123456",
    "gross_amount": 10000
},
"credit_card":{
    "secure" : true
},
"customer_details": {
    "first_name": "budi",
    "last_name": "pratama",
    "email": "budi.pra@example.com",
    "phone": "08111222333"
}

};
function bayar(){
snap.createTransaction(parameter)
.then((transaction)=>{
// transaction token
let transactionToken = transaction.token;
console.log('transactionToken:',transactionToken);
})
}

Hi @bobwatcherx did you send Snap request via frontend (ReactJS)? This library/package is mainly NOT FOR FRONTEND (Browser's javascript) usage, but for backend (Node JS server). You need to send Snap request via backend (NodeJS) then send the token response from the backend to your front-end. For the details please follow the instructions from the link above.

Thank you

Halo tim midtrans,

saya memakai react js dan sudah menggunakan contoh yg ini :

useEffect(() => {
const snapSrcUrl = 'https://app.sandbox.midtrans.com/snap/snap.js';
const myMidtransClientKey = 'your-client-key-goes-here'; //change this according to your client-key

const script = document.createElement('script');
script.src = snapSrcUrl;
script.setAttribute('data-client-key', myMidtransClientKey);
script.async = true;

document.body.appendChild(script);

return () => {
document.body.removeChild(script);
}
}, []);

akan tetapi ketika halaman tampil, muncul error :

DevTools failed to load source map: Could not load content for https://d2f3dnusg0rbp7.cloudfront.net/snap/assets/snap-popup-app.sandbox.js.map: HTTP error: status code 403, net::ERR_HTTP_RESPONSE_CODE_FAILURE

adakah yg bisa bantu ? trims

[sudah solved]
error di atas muncul karena bawaan browser, jadi bisa diabaikan

Solusi di Angular:

index.html

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>SNAP</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <script type="text/javascript"
		src="https://app.stg.midtrans.com/snap/snap.js"
    data-client-key="YOUR CLIENT KEY ID"></script>
</head>
<body style="overflow-y: hidden;">
  <app-root></app-root>
</body>
</html>

component.ts

import { Component } from '@angular/core';
import { ApiService } from 'src/app/api-service.service';
import { Router } from '@angular/router';

declare var snap:any;
....
export class CouponCartComponent {
  getToken()
  {
    .....
     const token = //get from your endpoint
      this.displayPaymentPopup(token)
}
  displayPaymentPopup(token:any)
  {
    snap.pay(token);
  }
}