google-pay / flutter-plugin

Apache License 2.0
141 stars 129 forks source link

data is not json/Map<String, dynamic> #258

Closed cookii-king closed 4 months ago

cookii-king commented 4 months ago

I/FA (18120): Application backgrounded at: timestamp_millis: 1714220576475 I/flutter (18120): Error decoding JSON: type 'int' is not a subtype of type 'Map<String, dynamic>' [log] 5684 [log] MASTERCARD [log] PAYMENT_GATEWAY I/flutter (18120): Error decoding JSON: FormatException: Unexpected character (at character 1) I/flutter (18120): MASTERCARD I/flutter (18120): ^ I/flutter (18120): Error decoding JSON: type 'List' is not a subtype of type 'String' I/flutter (18120): Error decoding JSON: FormatException: Unexpected character (at character 1) I/flutter (18120): PAYMENT_GATEWAY I/flutter (18120): ^ [log] {"androidPayCards":[{"type":"AndroidPayCard","nonce":"","description":"Android Pay","consumed":false,"threeDSecureInfo":null,"details":{"bin":"","cardType":"MasterCard","isNetworkTokenized":false,"lastTwo":"84","lastFour":"***"},"binData":{"prepaid":"Unknown","healthcare":"Unknown","debit":"Unknown","durbinRegulated":"Unknown","commercial":"Unknown","payroll":"Unknown","issuingBank":"Unknown","countryOfIssuance":"Unknown","productId":"Unknown"}}]}

          onPaymentResult: (Map<String, dynamic> result) async {
                                              Map<String, dynamic> map = {};
                                              result.keys.forEach((key) {
                                                // log(key);
                                              });
                                              result.values.forEach((value) {
                                                if (value is Map<String, dynamic>) {
                                                  Map<String, dynamic> _map = value;
                                                  // log(value.toString());
                                                  _map.keys.forEach((_key) {
                                                    // log(_key);
                                                  });

                                                  _map.values.forEach((_value) {
                                                    if (_value is Map<String, dynamic>) {
                                                      // log(_value.toString());

                                                      _value.keys.forEach((__key) {
                                                        // log(__key);
                                                      });

                                                      _value.values.forEach((__value) {
                                                        // __value.
                                                        log(__value);
                                                        // map = jsonDecode(__value);
                                                        // log(__value.toString());
                                                        // log(jsonDecode(__value));
                                                        if (__value is String) {
                                                          try {
                                                            // Attempt to decode the JSON string to a Map.
                                                            map = jsonDecode(__value);
                                                            log(map["androidPayCards"]);
                                                            print(map);
                                                          } catch (e) {
                                                            // If decoding fails, handle the error (e.g., log it).
                                                            print('Error decoding JSON: $e');
                                                          }
                                                        }
                                                        if (__value is Map<String, dynamic>) {
                                                          __value.keys.forEach((___key) {
                                                            log(___key);
                                                          });
                                                          // __value.
                                                          // map = __value;
                                                          // log(__value.toString());
                                                          // log(map["androidPayCards"][0]["nonce"].toString());
                                                        }
                                                      });
                                                    }
                                                  });
                                                }
                                              });
                                            },

`[log] {apiVersion: 2, apiVersionMinor: 0, paymentMethodData: {description: Mastercard •••• , info: {cardDetails: , cardNetwork: MASTERCARD}, tokenizationData: {token: {"androidPayCards":[{"type":"AndroidPayCard","nonce":"","description":"Android Pay","consumed":false,"threeDSecureInfo":null,"details":{"bin":"","cardType":"MasterCard","isNetworkTokenized":false,"lastTwo":"**","lastFour":"***"},"binData":{"prepaid":"Unknown","healthcare":"Unknown","debit":"Unknown","durbinRegulated":"Unknown","commercial":"Unknown","payroll":"Unknown","issuingBank":"Unknown","countryOfIssuance":"Unknown","productId":"Unknown"}}]}, type: PAYMENT_GATEWAY}, type: CARD}}

error seems to happen with description Mastercard •••• *** because its not string

Am I missing something because I'm trying to pass the nonce to Braintree so that I can create a payment method

cookii-king commented 4 months ago

Ok I think I found a work around if anyone else is struggling.

 Padding(
                                  padding: const EdgeInsets.all(8.0),
                                  child: Builder(builder: (context) {
                                    if (googlePayConfig == null) {
                                      return Center(
                                        child: CircularProgressIndicator(
                                          color: white,
                                        ),
                                      );
                                    }

                                    Map<String, dynamic> convertValuesToString(Map<String, dynamic> originalMap) {
                                      Map<String, dynamic> newMap = {};

                                      originalMap.forEach((key, value) {
                                        if (value is Map<String, dynamic>) {
                                          // If the value is a nested map, recursively process it
                                          newMap[key] = convertValuesToString(value);
                                        } else if (value is String) {
                                          // Check if the string is actually a JSON string
                                          try {
                                            // Attempt to decode the JSON string
                                            final decodedValue = jsonDecode(value);
                                            // If decoding is successful, use the decoded value (which could be a Map or a List)
                                            newMap[key] = decodedValue;
                                          } catch (e) {
                                            // If decoding fails, it's not a JSON string, so just convert the value to a string
                                            newMap[key] = value;
                                          }
                                        } else {
                                          // For all other non-Map values, convert the value to a string
                                          newMap[key] = value.toString();
                                        }
                                      });

                                      return newMap;
                                    }

                                    void onPaymentResult(Map<String, dynamic> result) {
                                      Map<String, dynamic> processedResult = convertValuesToString(result);
                                      processedResult.forEach((key, value) {
                                        print('$key: $value');
                                      });

                                      // Now you can access the token as a Map<String, dynamic> or List<dynamic>
                                      var token = processedResult["paymentMethodData"]["tokenizationData"]["token"];
                                      if (token is Map<String, dynamic> || token is List<dynamic>) {
                                        log('Token is a Map<String, dynamic> or List<dynamic>: $token');
                                        // log(token["androidPayCards"][0]["nonce"].toString());
                                        String paymentMethodNonce = token["androidPayCards"][0]["nonce"];
                                        wallet.createPaymentMethod(FirebaseAuth.instance.currentUser?.uid ?? "", paymentMethodNonce);
                                      } else {
                                        print('Token is not a Map<String, dynamic> or List<dynamic>: $token');
                                      }
                                    }

                                    // Map<String, String> remapKeysToString(Map<String, dynamic> originalMap) {
                                    //   Map<String, String> newMap = {};

                                    //   void traverseMap(Map<String, dynamic> map, String prefix) {
                                    //     map.forEach((key, value) {
                                    //       String newKey = prefix.isEmpty ? key : '$prefix.$key';
                                    //       if (value is Map<String, dynamic>) {
                                    //         // If the value is a nested map, recursively traverse it
                                    //         traverseMap(value, newKey);
                                    //       } else {
                                    //         // Otherwise, add the key-value pair to the new map, converting the value to a string
                                    //         newMap[newKey] = value.toString();
                                    //       }
                                    //     });
                                    //   }

                                    //   traverseMap(originalMap, ''); // Start with an empty prefix
                                    //   return newMap;
                                    // }

                                    // Map<String, dynamic> convertValuesToString(Map<String, dynamic> originalMap) {
                                    //   Map<String, dynamic> newMap = {};

                                    //   originalMap.forEach((key, value) {
                                    //     if (value is Map<String, dynamic>) {
                                    //       // If the value is a nested map, recursively process it
                                    //       newMap[key] = convertValuesToString(value);
                                    //     } else {
                                    //       // Otherwise, convert the value to a string
                                    //       newMap[key] = value.toString();
                                    //     }
                                    //   });

                                    //   return newMap;
                                    // }

                                    return Row(
                                      children: [
                                        Expanded(
                                          child: GooglePayButton(
                                            height: 60,
                                            paymentConfiguration: googlePayConfig!,
                                            type: GooglePayButtonType.pay,
                                            onPaymentResult: onPaymentResult,
                                            // onPaymentResult: (Map<String, dynamic> result) async {
                                            //   // Map<String, String> flattenedMap = remapKeysToString(result);
                                            //   // flattenedMap.forEach((key, value) {
                                            //   //   print('$key: $value');
                                            //   // });

                                            //   Map<String, dynamic> processedResult = convertValuesToString(result);
                                            //   processedResult.forEach((key, value) {
                                            //     print('$key: $value');
                                            //   });
                                            //   // Map<String, dynamic> token = processedResult["paymentMethodData"]["tokenizationData"]["token"];
                                            //   // log(token.toString());
                                            //   // var token = processedResult["paymentMethodData"]["tokenizationData"]["token"];
                                            //   // if (token is Map<String, dynamic>) {
                                            //   //   print('Token is a Map<String, dynamic>: $token');
                                            //   // } else {
                                            //   //   print('Token is not a Map<String, dynamic>: $token');
                                            //   // }
                                            //   var token = processedResult["paymentMethodData"]["tokenizationData"]["token"];
                                            //   if (token is Map<String, dynamic> || token is List<dynamic>) {
                                            //     log('Token is a Map<String, dynamic> or List<dynamic>: $token');
                                            //   } else {
                                            //     print('Token is not a Map<String, dynamic> or List<dynamic>: $token');
                                            //   }

                                            //   // log(result.toString());
                                            //   // Map<String, dynamic> map = {};
                                            //   // result.keys.forEach((key) {
                                            //   //   // log(key);
                                            //   // });
                                            //   // result.values.forEach((value) {
                                            //   //   if (value is Map<String, dynamic>) {
                                            //   //     Map<String, dynamic> _map = value;
                                            //   //     // log(value.toString());
                                            //   //     _map.keys.forEach((_key) {
                                            //   //       // log(_key);
                                            //   //     });

                                            //   //     _map.values.forEach((_value) {
                                            //   //       if (_value is Map<String, dynamic>) {
                                            //   //         // log(_value.toString());

                                            //   //         _value.keys.forEach((__key) {
                                            //   //           // log(__key);
                                            //   //         });

                                            //   //         _value.values.forEach((__value) {
                                            //   //           // __value.
                                            //   //           log(__value);
                                            //   //           // map = jsonDecode(__value);
                                            //   //           // log(__value.toString());
                                            //   //           // log(jsonDecode(__value));
                                            //   //           if (__value is String) {
                                            //   //             try {
                                            //   //               // Attempt to decode the JSON string to a Map.
                                            //   //               map = jsonDecode(__value);
                                            //   //               log(map["androidPayCards"]);
                                            //   //               print(map);
                                            //   //             } catch (e) {
                                            //   //               // If decoding fails, handle the error (e.g., log it).
                                            //   //               print('Error decoding JSON: $e');
                                            //   //             }
                                            //   //           }
                                            //   //           if (__value is Map<String, dynamic>) {
                                            //   //             __value.keys.forEach((___key) {
                                            //   //               log(___key);
                                            //   //             });
                                            //   //             // __value.
                                            //   //             // map = __value;
                                            //   //             // log(__value.toString());
                                            //   //             // log(map["androidPayCards"][0]["nonce"].toString());
                                            //   //           }
                                            //   //         });
                                            //   //       }
                                            //   //     });
                                            //   //   }
                                            //   // });
                                            // },
                                            paymentItems: [
                                              PaymentItem(
                                                label: 'Total',
                                                amount: double.tryParse(depositAmount.toString())!.toStringAsFixed(2),
                                                status: PaymentItemStatus.final_price,
                                              )
                                            ],
                                          ),
                                        ),
                                      ],
                                    );
                                  }),
                                ),

Don't mind the comments I was debugging.