Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

task: add support for cart items #32

Merged
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ dependencies {
//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+"

implementation "com.github.gr4vy:gr4vy-android:v1.6.3"
implementation "com.github.gr4vy:gr4vy-android:v1.7.4"
}

if (isNewArchitectureEnabled()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
import android.os.Bundle;
import android.util.Log;

import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;

@ReactModule(name = EmbedReactNativeModule.NAME)
public class EmbedReactNativeModule extends ReactContextBaseJavaModule {
public static final String NAME = "EmbedReactNative";
Expand Down Expand Up @@ -61,6 +65,25 @@ public static <T> T coalesce(T... items) {
return null;
}

public static Object getMapOptionalValue(ReadableMap map, String key) {
Copy link
Collaborator Author

@luca-gr4vy luca-gr4vy Jun 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ReadableMap doesn't seem to have a method to get options values and fallback to null, so adding one here

if (map.hasKey(key)) {
if (!map.isNull(key)) {
switch (map.getType(key)) {
case Number:
victormferrara marked this conversation as resolved.
Show resolved Hide resolved
return map.getInt(key);
case String:
return map.getString(key);
case Array:
return map.getArray(key);
default:
return null;
}
}
return null;
}
return null;
}

public EmbedReactNativeModule(ReactApplicationContext context) {
super(context);

Expand Down Expand Up @@ -120,6 +143,36 @@ private static WritableArray convertCartItemsToJson(ReadableArray cartItemsArray
cartItemWritableMap.putString("name", cartItemMap.getString("name"));
cartItemWritableMap.putInt("quantity", cartItemMap.getInt("quantity"));
cartItemWritableMap.putInt("unitAmount", cartItemMap.getInt("unitAmount"));

List<String> optionalProps = new ArrayList<String>(Arrays.asList(
victormferrara marked this conversation as resolved.
Show resolved Hide resolved
"discountAmount",
"taxAmount",
"externalIdentifier",
"sku",
"productUrl",
"imageUrl",
"categories",
"productType"
));
for (String prop : optionalProps) {
Object value = getMapOptionalValue(cartItemMap, prop);
if (value != null) {
switch (value.getClass().getSimpleName()) {
case "Integer":
cartItemWritableMap.putInt(prop, (Integer) value);
break;
victormferrara marked this conversation as resolved.
Show resolved Hide resolved
case "String":
cartItemWritableMap.putString(prop, (String) value);
break;
case "ReadableNativeArray":
cartItemWritableMap.putArray(prop, (ReadableArray) value);
default:
break;
}
}
}


cartItemsWritableArray.pushMap(cartItemWritableMap);
}
return cartItemsWritableArray;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableArray;

import org.json.JSONArray;
import org.json.JSONObject;
Expand All @@ -20,6 +21,7 @@

import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;

import static com.gr4vy.embedreactnative.EmbedReactNativeModule.coalesce;
import static com.gr4vy.embedreactnative.EmbedReactNativeModule.EXTRA_GR4VY_ID;
Expand All @@ -45,8 +47,6 @@
import static com.gr4vy.embedreactnative.EmbedReactNativeModule.EXTRA_PAYMENT_SOURCE;
import static com.gr4vy.embedreactnative.EmbedReactNativeModule.EXTRA_CART_ITEMS;

import java.util.HashMap;

public class Gr4vyActivity extends ComponentActivity implements Gr4vyResultHandler {
private Gr4vySDK gr4vySDK;
private final ActivityResultRegistry activityResultRegistry = this.getActivityResultRegistry();
Expand Down Expand Up @@ -186,9 +186,38 @@ protected static List<CartItem> convertCartItems(String cartItemsJson) {
for (int i = 0; i < cartItemsJsonArray.length(); i++) {
JSONObject cartItemJsonObject = cartItemsJsonArray.getJSONObject(i);
String name = cartItemJsonObject.getString("name");
int quantity = cartItemJsonObject.getInt("quantity");
int unitAmount = cartItemJsonObject.getInt("unitAmount");
CartItem cartItem = new CartItem(name, quantity, unitAmount);
Integer quantity = cartItemJsonObject.getInt("quantity");
Integer unitAmount = cartItemJsonObject.getInt("unitAmount");
Integer discountAmount = (Integer) cartItemJsonObject.opt("discountAmount");
Integer taxAmount = (Integer) cartItemJsonObject.opt("taxAmount");
String externalIdentifier = (String) cartItemJsonObject.opt("externalIdentifier");
String sku = (String) cartItemJsonObject.opt("sku");
String productUrl = (String) cartItemJsonObject.opt("productUrl");
String imageUrl = (String) cartItemJsonObject.opt("imageUrl");
String productType = (String) cartItemJsonObject.opt("productType");

JSONArray categoriesArray = (JSONArray) cartItemJsonObject.opt("categories");
List<String> categories = null;
if (categoriesArray != null) {
categories = new ArrayList<String>();
for (int j = 0; j < categoriesArray.length(); j++) {
categories.add(categoriesArray.getString(j));
}
}

CartItem cartItem = new CartItem(
name,
quantity,
unitAmount,
discountAmount,
taxAmount,
externalIdentifier,
sku,
productUrl,
imageUrl,
categories,
productType
);
cartItemList.add(cartItem);
}
} catch (JSONException e) {
Expand Down Expand Up @@ -284,6 +313,7 @@ public void onStart() {
requireSecurityCode,
shippingDetailsId,
merchantAccountId,
null, // TODO: pass connectionOptions
debugMode);

sdkLaunched = true;
Expand Down
2 changes: 1 addition & 1 deletion example/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ GEM
nap (1.1.0)
netrc (0.11.0)
public_suffix (4.0.7)
rexml (3.2.5)
rexml (3.2.8)
ruby-macho (2.5.1)
typhoeus (1.4.0)
ethon (>= 0.9.0)
Expand Down
2 changes: 1 addition & 1 deletion example/android/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ GEM
trailblazer-option (>= 0.1.1, < 0.2.0)
uber (< 0.2.0)
retriable (3.1.2)
rexml (3.2.5)
rexml (3.2.8)
rouge (2.0.7)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
Expand Down
2 changes: 1 addition & 1 deletion example/ios/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ GEM
trailblazer-option (>= 0.1.1, < 0.2.0)
uber (< 0.2.0)
retriable (3.1.2)
rexml (3.2.5)
rexml (3.2.8)
rouge (2.0.7)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
Expand Down
10 changes: 5 additions & 5 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@ PODS:
- FlipperKit/FlipperKitNetworkPlugin
- fmt (6.2.1)
- glog (0.3.5)
- gr4vy-embed-react-native (1.0.0):
- gr4vy-ios (= 1.6.1)
- gr4vy-embed-react-native (1.1.0):
- gr4vy-ios (= 2.1.1)
- React-Core
- gr4vy-ios (1.6.1)
- gr4vy-ios (2.1.1)
- hermes-engine (0.71.8):
- hermes-engine/Pre-built (= 0.71.8)
- hermes-engine/Pre-built (0.71.8)
Expand Down Expand Up @@ -627,8 +627,8 @@ SPEC CHECKSUMS:
FlipperKit: cbdee19bdd4e7f05472a66ce290f1b729ba3cb86
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
gr4vy-embed-react-native: fa2c871707b970da45a94af0611e1c0ddeb70929
gr4vy-ios: e983133ec0e3beed759e3ee07aeca7bb480c8b10
gr4vy-embed-react-native: a31b28e27e088e1f6520e88009e147ccde4855af
gr4vy-ios: ae967d91a6451086f544b27867b4e910d04926df
hermes-engine: 47986d26692ae75ee7a17ab049caee8864f855de
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
nodejs-mobile-react-native: e35e7ed7ecfca168f168983e9557f1c5278d864b
Expand Down
4 changes: 3 additions & 1 deletion example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
},
"resolutions": {
"braces": "^3.0.3",
"tar": "^6.2.1"
"tar": "^6.2.1",
"ws": "^7.5.10",
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix ws vulnerability

"react-native/ws": "^6.2.3"
}
}
18 changes: 9 additions & 9 deletions example/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5335,18 +5335,18 @@ write-file-atomic@^2.3.0:
imurmurhash "^0.1.4"
signal-exit "^3.0.2"

ws@^6.2.2:
version "6.2.2"
resolved "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz#dd5cdbd57a9979916097652d78f1cc5faea0c32e"
integrity sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==
ws@^6.2.2, ws@^7, ws@^7.5.1, ws@^7.5.10:
version "7.5.10"
resolved "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9"
integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==

ws@^6.2.3:
version "6.2.3"
resolved "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz#ccc96e4add5fd6fedbc491903075c85c5a11d9ee"
integrity sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==
dependencies:
async-limiter "~1.0.0"

ws@^7, ws@^7.5.1:
version "7.5.9"
resolved "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591"
integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==

xcode@^2.0.0:
version "2.1.0"
resolved "https://registry.npmjs.org/xcode/-/xcode-2.1.0.tgz#bab64a7e954bb50ca8d19da7e09531c65a43ecfe"
Expand Down
2 changes: 1 addition & 1 deletion gr4vy-embed-react-native.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Pod::Spec.new do |s|
s.source_files = "ios/**/*.{h,m,mm,swift}"

s.dependency "React-Core"
s.dependency "gr4vy-ios", "1.6.1"
s.dependency "gr4vy-ios", "2.1.1"

# Don't install the dependencies when we run `pod install` in the old architecture.
if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
Expand Down
52 changes: 37 additions & 15 deletions ios/EmbedReactNative.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class EmbedReactNative: NSObject {
paymentSourceConverted = Gr4vyPaymentSource(rawValue: paymentSource!)
}

DispatchQueue.main.async(execute: {
DispatchQueue.main.async(execute: {
guard let gr4vy = Gr4vy(gr4vyId: gr4vyId,
token: token,
amount: amount,
Expand Down Expand Up @@ -67,7 +67,7 @@ class EmbedReactNative: NSObject {
completion(gr4vy)
})
}

func buildTheme(_ source: [String: [String: String?]?]?) -> Gr4vyTheme? {
guard let theme = source,
let fonts = theme["fonts"] ?? [:],
Expand Down Expand Up @@ -148,7 +148,7 @@ class EmbedReactNative: NSObject {
)
)
}

func convertStatementDescriptor(_ source: [String: String?]?) -> Gr4vyStatementDescriptor? {
guard let statementDescriptor = source,
let name = statementDescriptor["name"] ?? "",
Expand All @@ -158,7 +158,7 @@ class EmbedReactNative: NSObject {
let url = statementDescriptor["url"] ?? "" else {
return nil
}

return Gr4vyStatementDescriptor(
name: name,
description: description,
Expand All @@ -167,7 +167,7 @@ class EmbedReactNative: NSObject {
url: url
)
}

func convertCartItems(_ cartItems: NSArray?) -> [Gr4vyCartItem] {
guard let cartItems = cartItems else {
return []
Expand All @@ -181,17 +181,39 @@ class EmbedReactNative: NSObject {
let unitAmount = dict["unitAmount"] as? Int else {
return []
}
result.append(Gr4vyCartItem(name: name, quantity: quantity, unitAmount: unitAmount))
let discountAmount = dict["discountAmount"] as? Int ?? 0
let taxAmount = dict["taxAmount"] as? Int ?? 0
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is waiting for the type update in the iOS SDK https://github.com/gr4vy/gr4vy-ios/blob/main/gr4vy-iOS/Models/Gr4vyCartItem.swift. We don't want to pass a default of 0 as this would cause a mismatch between the passed prop and the value in the JWT if people don't pass anything

let externalIdentifier = dict["externalIdentifier"] as? String
let sku = dict["sku"] as? String
let productUrl = dict["productUrl"] as? String
let imageUrl = dict["imageUrl"] as? String
let categories = dict["categories"] as? [String]
let productType = dict["productType"] as? String
result.append(
Gr4vyCartItem(
name: name,
quantity: quantity,
unitAmount: unitAmount,
discountAmount: discountAmount,
taxAmount: taxAmount,
externalIdentifier: externalIdentifier,
sku: sku,
productUrl: productUrl,
imageUrl: imageUrl,
categories: categories,
productType: productType
)
)
}

return result
}

func convertStore(_ store: Any?) -> Gr4vyStore? {
guard let storeValue = store else {
return nil
}

if let storeBool = storeValue as? Bool {
return storeBool ? .true : .false
} else if let storeString = store as? String {
Expand All @@ -202,10 +224,10 @@ class EmbedReactNative: NSObject {
return nil
}
}

return nil
}

@objc
func constantsToExport() -> [AnyHashable : Any]! {
return [
Expand All @@ -214,7 +236,7 @@ class EmbedReactNative: NSObject {
GR4VY_ERROR: GR4VY_ERROR
]
}

@objc
func showPaymentSheet(_ config: [String: Any])
{
Expand Down Expand Up @@ -253,7 +275,7 @@ class EmbedReactNative: NSObject {
)
return
}

gr4vyInit(gr4vyId: gr4vyId,
token: token,
amount: Int(amount),
Expand Down Expand Up @@ -291,11 +313,11 @@ class EmbedReactNative: NSObject {

DispatchQueue.main.async(execute: {
let presentingViewController = RCTPresentedViewController()

gr4vy!.launch(
presentingViewController: presentingViewController!,
onEvent: { event in

switch event {
case .transactionFailed(let transactionID, let status, let paymentMethodID):
EmbedReactNativeEvents.emitter.sendEvent(
Expand Down Expand Up @@ -352,7 +374,7 @@ class EmbedReactNative: NSObject {
})
}
}

@objc
static func requiresMainQueueSetup() -> Bool {
return true
Expand Down
Loading
Loading