Mhamdans17 commited on
Commit
e06ef8c
·
1 Parent(s): fe79eec

feat: implement automatic fallback from QRIS to QRISC in tripay service

Browse files
Files changed (1) hide show
  1. services/tripay.go +77 -50
services/tripay.go CHANGED
@@ -123,29 +123,7 @@ func CreateTripayTransaction(
123
  proxyURLStr = config.GlobalConfig.TripayProxyURL
124
  }
125
 
126
- // Hitung signature
127
- signature := CalculateSignature(orderNumber, amount, mCode, privKey)
128
-
129
- // Persiapkan payload request
130
- payload := TripayCreateRequest{
131
- Method: paymentMethod,
132
- MerchantRef: orderNumber,
133
- Amount: amount,
134
- CustomerName: customerName,
135
- CustomerEmail: customerEmail,
136
- CustomerPhone: customerPhone,
137
- OrderItems: items,
138
- Signature: signature,
139
- }
140
-
141
- jsonBytes, err := json.Marshal(payload)
142
- if err != nil {
143
- return nil, fmt.Errorf("gagal merancang payload Tripay: %v", err)
144
- }
145
-
146
- apiURL := getTripayBaseURL() + "/transaction/create"
147
- log.Printf("[TRIPAY] Mengirim request tagihan ke: %s (CompanyID=%d)", apiURL, companyID)
148
-
149
  transport := &http.Transport{}
150
  if proxyURLStr != "" {
151
  proxyURL, err := url.Parse(proxyURLStr)
@@ -161,42 +139,91 @@ func CreateTripayTransaction(
161
  Transport: transport,
162
  Timeout: 15 * time.Second,
163
  }
164
- req, err := http.NewRequest("POST", apiURL, bytes.NewBuffer(jsonBytes))
165
- if err != nil {
166
- return nil, fmt.Errorf("gagal membuat http request: %v", err)
 
 
167
  }
168
 
169
- // Atur headers
170
- req.Header.Set("Content-Type", "application/json")
171
- req.Header.Set("Authorization", "Bearer "+apiKey)
172
 
173
- resp, err := client.Do(req)
174
- if err != nil {
175
- return nil, fmt.Errorf("koneksi HTTP ke Tripay gagal: %v", err)
176
- }
177
- defer resp.Body.Close()
 
 
 
 
 
 
 
 
 
 
178
 
179
- bodyBytes, err := io.ReadAll(resp.Body)
180
- if err != nil {
181
- return nil, fmt.Errorf("gagal membaca response body Tripay: %v", err)
182
- }
183
 
184
- if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated {
185
- log.Printf("[TRIPAY] Response error: Status=%d, Body=%s", resp.StatusCode, string(bodyBytes))
186
- return nil, fmt.Errorf("tripay mengembalikan status error %d", resp.StatusCode)
187
- }
188
 
189
- var tripayResp TripayCreateResponse
190
- if err := json.Unmarshal(bodyBytes, &tripayResp); err != nil {
191
- return nil, fmt.Errorf("gagal parse JSON response Tripay: %v", err)
192
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
 
194
- if !tripayResp.Success {
195
- return nil, fmt.Errorf("tripay gagal memproses: %s", tripayResp.Message)
196
  }
197
 
198
- log.Printf("[TRIPAY] Sukses membuat transaksi! Ref=%s, URL=%s", tripayResp.Data.Reference, tripayResp.Data.CheckoutURL)
199
- return &tripayResp, nil
200
  }
201
 
202
  // VerifyTripaySignature memvalidasi keaslian callback webhook dari Tripay
 
123
  proxyURLStr = config.GlobalConfig.TripayProxyURL
124
  }
125
 
126
+ // Persiapkan proxy transport
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
  transport := &http.Transport{}
128
  if proxyURLStr != "" {
129
  proxyURL, err := url.Parse(proxyURLStr)
 
139
  Transport: transport,
140
  Timeout: 15 * time.Second,
141
  }
142
+
143
+ // Buat daftar metode pembayaran yang akan dicoba (jika default QRIS, tambahkan QRISC sebagai fallback otomatis)
144
+ methodsToTry := []string{paymentMethod}
145
+ if paymentMethod == "QRIS" {
146
+ methodsToTry = append(methodsToTry, "QRISC")
147
  }
148
 
149
+ var lastError error
150
+ var tripayResp TripayCreateResponse
 
151
 
152
+ for _, currentMethod := range methodsToTry {
153
+ // Hitung signature (sama untuk semua method karena rumusnya hanya: merchantCode + merchantRef + amount)
154
+ signature := CalculateSignature(orderNumber, amount, mCode, privKey)
155
+
156
+ // Persiapkan payload request
157
+ payload := TripayCreateRequest{
158
+ Method: currentMethod,
159
+ MerchantRef: orderNumber,
160
+ Amount: amount,
161
+ CustomerName: customerName,
162
+ CustomerEmail: customerEmail,
163
+ CustomerPhone: customerPhone,
164
+ OrderItems: items,
165
+ Signature: signature,
166
+ }
167
 
168
+ jsonBytes, err := json.Marshal(payload)
169
+ if err != nil {
170
+ return nil, fmt.Errorf("gagal merancang payload Tripay: %v", err)
171
+ }
172
 
173
+ apiURL := getTripayBaseURL() + "/transaction/create"
174
+ log.Printf("[TRIPAY] Mengirim request tagihan ke: %s (Method=%s, CompanyID=%d)", apiURL, currentMethod, companyID)
 
 
175
 
176
+ req, err := http.NewRequest("POST", apiURL, bytes.NewBuffer(jsonBytes))
177
+ if err != nil {
178
+ return nil, fmt.Errorf("gagal membuat http request: %v", err)
179
+ }
180
+
181
+ // Atur headers
182
+ req.Header.Set("Content-Type", "application/json")
183
+ req.Header.Set("Authorization", "Bearer "+apiKey)
184
+
185
+ resp, err := client.Do(req)
186
+ if err != nil {
187
+ lastError = fmt.Errorf("koneksi HTTP ke Tripay gagal: %v", err)
188
+ continue
189
+ }
190
+
191
+ bodyBytes, err := io.ReadAll(resp.Body)
192
+ resp.Body.Close()
193
+ if err != nil {
194
+ lastError = fmt.Errorf("gagal membaca response body Tripay: %v", err)
195
+ continue
196
+ }
197
+
198
+ if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated {
199
+ log.Printf("[TRIPAY] Response error: Status=%d, Body=%s", resp.StatusCode, string(bodyBytes))
200
+
201
+ // Ambil deskripsi error untuk dicatat ke lastError
202
+ var errorResp struct {
203
+ Success bool `json:"success"`
204
+ Message string `json:"message"`
205
+ }
206
+ _ = json.Unmarshal(bodyBytes, &errorResp)
207
+
208
+ lastError = fmt.Errorf("tripay mengembalikan status error %d: %s", resp.StatusCode, errorResp.Message)
209
+ continue
210
+ }
211
+
212
+ if err := json.Unmarshal(bodyBytes, &tripayResp); err != nil {
213
+ lastError = fmt.Errorf("gagal parse JSON response Tripay: %v", err)
214
+ continue
215
+ }
216
+
217
+ if !tripayResp.Success {
218
+ lastError = fmt.Errorf("tripay gagal memproses: %s", tripayResp.Message)
219
+ continue
220
+ }
221
 
222
+ log.Printf("[TRIPAY] Sukses membuat transaksi dengan Method=%s! Ref=%s, URL=%s", currentMethod, tripayResp.Data.Reference, tripayResp.Data.CheckoutURL)
223
+ return &tripayResp, nil
224
  }
225
 
226
+ return nil, lastError
 
227
  }
228
 
229
  // VerifyTripaySignature memvalidasi keaslian callback webhook dari Tripay