Midtrans/midtrans-php

Trying to access array offset on value of type null

luqmansolihin opened this issue · 8 comments

endpoint:
https://ecommerce.tanjidor.id/api/v1/payment/callback

status:
{
"va_numbers": [
{
"bank": "bca",
"va_number": "98513982169"
}
],
"payment_amounts": [],
"transaction_time": "2022-11-17 16:51:28",
"gross_amount": "10000.00",
"currency": "IDR",
"order_id": "202211171668678688",
"payment_type": "bank_transfer",
"signature_key": "992e063084e617f1507d51ebc49a33d9578ecbc0acf040f8088b43203ffed78bd1d52e14c1a237bfe17865725c0e1ee75326c074a81896cd54d3f11d81c9c8a4",
"status_code": "201",
"transaction_id": "afc8937e-8b4b-447c-bcf2-da22e0f099ba",
"transaction_status": "pending",
"fraud_status": "accept",
"status_message": "Success, transaction is found",
"merchant_id": "M098513"
}

error:
{
"class": "ErrorException",
"message": "Trying to access array offset on value of type null",
"code": 0,
"file": "/var/www/ecommerce_api/vendor/midtrans/midtrans-php/Midtrans/Notification.php:26",
"trace": [
"/var/www/ecommerce_api/vendor/midtrans/midtrans-php/Midtrans/Notification.php:26",
"/var/www/ecommerce_api/app/Services/PaymentService.php:59",
"/var/www/ecommerce_api/routes/Api/V1/api.php:149",
"/var/www/ecommerce_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php:238",
"/var/www/ecommerce_api/vendor/laravel/framework/src/Illuminate/Routing/Route.php:208",
"/var/www/ecommerce_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php:721",
"/var/www/ecommerce_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:128",
"/var/www/ecommerce_api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php:50",
"/var/www/ecommerce_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167",
"/var/www/ecommerce_api/vendor/laravel/sanctum/src/Http/Middleware/EnsureFrontendRequestsAreStateful.php:33",
"/var/www/ecommerce_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:128",
"/var/www/ecommerce_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:103",
"/var/www/ecommerce_api/vendor/laravel/sanctum/src/Http/Middleware/EnsureFrontendRequestsAreStateful.php:34",
"/var/www/ecommerce_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167",
"/var/www/ecommerce_api/app/Http/Middleware/JsonResponseMiddleware.php:37",
"/var/www/ecommerce_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167",
"/var/www/ecommerce_api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:103",
"/var/www/ecommerce_api/vendor/laravel/framework/src/Illuminate/Routing/Router.php:723"
]
}

Untuk kasus seperti ini solusinya bagaimana ya?

Hi @luqmansolihin

Saya mencoba mencari pesan eror: Trying to access array offset on value of type null yang berkaitan dengan Laravel, berdasarkan artikel di sini, sepertinya eror tersebut disebabkan karena menggunakan PHP version tertentu dan juga Laravel versi yang lama.

Salah satu solusinya adalah dengan melakukan update composer dengan command berikut: composer update, apakah sudah mencoba melakukan update composer?

Terkait bagaimana cara menghandle notification dari Midtrans, silakan melihat dokumentasi kami di sini: https://docs.midtrans.com/en/after-payment/http-notification?id=best-practice-to-handle-notification.

Terima kasih.

Sudah saya lakukan composer update.

PHP yang saya gunakan juga sudah diatas versi 7.4.*. PHP yang saya gunakan versi 8.1.2. Laravel yang saya gunakan versi 8.78. Tapi, masih dengan error yang yang sama Trying to access array offset on value of type null.

Berdasarkan trace file error nya pada file ini /var/www/ecommerce_api/vendor/midtrans/midtrans-php/Midtrans/Notification.php:26 pada line ini $status_response = Transaction::status($raw_notification['transaction_id']);

Apakah ada solusi lain untuk kasus ini?

Setelah saya dump($raw_notification) ternyata hasilnya Null.
Sementara pada history di dashboard midtrans terdapat error dengan response dead Failed after automatic attempts.

untuk kasus ini solusinya bagaimana ya?

Hi @luqmansolihin setelah saya coba cek di github laravel kemungkinan memang ada issue PHP versi 7.4 dengan framework laravel.

Mungkin bisa coba downgrade ke php 7.2 atau 7.3
Refer ke issue berikut
laravel/framework#30737 (comment)
laravel/framework#30737 (comment)

Terima kasih

untuk solusi yang dead Failed after automatic attempts. itu bagaimana ya?

untuk solusi yang dead Failed after automatic attempts. itu bagaimana ya?

Solusinya adalah endpoint ini https://ecommerce.tanjidor.id/api/v1/payment/callback harus work dulu dan bisa menerima http notif Midtrans.
Ketika Midtrans mengirimkan http notif namun gagal akan ada percobaan retry sebanyak 5 kali. Jika sesudah retry endpoint yang di set masih gagal menerima notif maka akan muncul dead failed.

Halo @luqmansolihin , saya se-tim dengan @Andrenzo17, akan bantu menambahkan penjelasan. Jika kita runut issuenya:

  • Kenapa throw error Trying to access array offset on value of type null?
  • Ini adalah generic error msg dari PHP yg menginfokan: Array yg sedang diakses tidak mempunya key/index yg ingin dibaca.
    • Ini adalah error generic yg bisa terjadi di general Array di PHP, jadi likely tidak berhubungan dengan PHP version atau Laravel version ataupun link yg di share sebelumnya cc: FYI @Andrenzo17
  • Kenapa bisa begitu? Karena codenya $raw_notification['transaction_id'], mencoba mengakses transaction_id dari array $raw_notification. Kenapa bisa begitu?
  • Karena $raw_notification null. Kenapa bisa null?
  • $raw_notification seharusnya akan didapat dari HTTP body dari HTTP request yg masuk ke controller tersebut. Nah sedangkan kalau HTTP body tidak berhasil dibaca, maka akan mendapat null.

Apa yg potensi bisa menyebabkan issue tersebut? ada banyak kemungkinan yg perlu dicek:

  • request yang masuk bukan HTTP POST, jika request yang masuk bukan POST, maka biasanya tidak ada HTTP Body, maka akan gagal di baca.
    • cek apakah di level backend (PHP, Laravel dsb) ada yang mengubah request dari POST jadi GET? ada redirect?
    • cek apakah di level infrastructure (network, NGinx, firewall, proxy, dsb) ada yang mengubah request dari POST jadi GET? ada redirect?
  • request yang masuk tidak mempunyai HTTP body, maka akan gagal di baca.
    • cek apakah ada "sesuatu" yang menghilangkan HTTP body di level backend/infra, seperti point sebelumnya.
  • code berikut , yang digunakan untuk membaca HTTP body, gagal dijalankan di backend (PHP, Laravel, dsb) anda.
    • mungkin ada salah config di backend anda yg menyebabkan code tersebut tidak berjalan as expected.

Info tambahan, anda bisa test dengan mengirim request seperti berikut:

curl -vvv -X POST \
  https://ecommerce.tanjidor.id/api/v1/payment/callback \
  -H 'User-Agent: Veritrans' \
  -H 'Accept: application/json'\
  -H 'Content-Type: application/json' \
  -d '{
      "va_numbers": [
        {
          "va_number": "98513982169",
          "bank": "bca"
        }
      ],
      "transaction_time": "2022-11-17 16:51:28",
      "transaction_status": "pending",
      "transaction_id": "afc8937e-8b4b-447c-bcf2-da22e0f099ba",
      "status_message": "midtrans payment notification",
      "status_code": "201",
      "signature_key": "992e063084e617f1507d51ebc49a33d9578ecbc0acf040f8088b43203ffed78bd1d52e14c1a237bfe17865725c0e1ee75326c074a81896cd54d3f11d81c9c8a4",
      "payment_type": "bank_transfer",
      "payment_amounts": [],
      "order_id": "202211171668678688",
      "merchant_id": "M098513",
      "gross_amount": "10000.00",
      "fraud_status": "accept",
      "currency": "IDR"
    }
  }'

Bisa execute via terminal atau import ke Postman, kemudian kirim requestnya.

Yang perlu anda pastikan adalah:

  • Ketika mendapat request itu, HTTP Bodynya (yang berupa JSON) harus bisa diterima di sisi backend Anda. Jika bodynya hilang, maka ada yang salah dengan infra atau backend anda & perlu dicek serta perbaiki.

Hal di atas adalah di luar scope & visibility Midtrans, karena adanya bukan di Midtrans. Jadi silahkan dicek.
Terima kasih.

Terimkasih, issue ini akan saya close.
Permasalahannya karena package dari Laravelnya sendiri. Saya menggunakan Laravel Octane yang memang terdapat issue pada php://input seperti ini:
laravel octane problem with php://input