Skip to content

Commit

Permalink
Merge pull request #61 from cashfree/feature/card_component
Browse files Browse the repository at this point in the history
Cashfree Card component
  • Loading branch information
kishan-cashfree authored Jul 15, 2024
2 parents b36e6d2 + 84e1519 commit a927fd7
Show file tree
Hide file tree
Showing 25 changed files with 672 additions and 41 deletions.
2 changes: 1 addition & 1 deletion example/__tests__/App-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/
import 'react-native';
import React from 'react';
import App from '../App';
import App from '../src/App';
// Note: test renderer must be required after react-native.
import renderer from 'react-test-renderer';
it('renders correctly', () => {
Expand Down
2 changes: 1 addition & 1 deletion example/__tests__/App-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import 'react-native';
import React from 'react';
import App from '../App';
import App from '../src/App';

// Note: test renderer must be required after react-native.
import renderer from 'react-test-renderer';
Expand Down
2 changes: 1 addition & 1 deletion example/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/

import {AppRegistry} from 'react-native';
import App from './App';
import App from './src/App';
import {name as appName} from './app.json';

AppRegistry.registerComponent(appName, () => App);
1 change: 1 addition & 0 deletions example/ios/.ruby-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.2.1
15 changes: 9 additions & 6 deletions example/ios/CashfreePgApiExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@
83CBB9F71A601CBA00E9B192 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1210;
BuildIndependentTargetsInParallel = YES;
LastUpgradeCheck = 1530;
TargetAttributes = {
00E356ED1AD99517003FC87E = {
CreatedOnToolsVersion = 6.2;
Expand Down Expand Up @@ -432,6 +433,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = C5B5349BB9FA979B25D7E6E5 /* Pods-CashfreePgApiExample-CashfreePgApiExampleTests.debug.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_LOADER = "$(TEST_HOST)";
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
Expand Down Expand Up @@ -459,6 +461,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = B985D2D875A593D3BD49C0E4 /* Pods-CashfreePgApiExample-CashfreePgApiExampleTests.release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_LOADER = "$(TEST_HOST)";
COPY_PHASE_STRIP = NO;
INFOPLIST_FILE = CashfreePgApiExampleTests/Info.plist;
Expand Down Expand Up @@ -566,7 +569,7 @@
COPY_PHASE_STRIP = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
Expand Down Expand Up @@ -639,7 +642,7 @@
COPY_PHASE_STRIP = YES;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
Expand Down Expand Up @@ -682,7 +685,7 @@
00E356F71AD99517003FC87E /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
defaultConfigurationName = Debug;
};
13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "CashfreePgApiExample" */ = {
isa = XCConfigurationList;
Expand All @@ -691,7 +694,7 @@
13B07F951A680F5B00A75B9A /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
defaultConfigurationName = Debug;
};
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "CashfreePgApiExample" */ = {
isa = XCConfigurationList;
Expand All @@ -700,7 +703,7 @@
83CBBA211A601CBA00E9B192 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
defaultConfigurationName = Debug;
};
/* End XCConfigurationList section */
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1210"
LastUpgradeVersion = "1530"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down Expand Up @@ -50,16 +50,19 @@
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<PathRunnable
runnableDebuggingMode = "0"
FilePath = "/Users/kishankumarmaurya/Library/Developer/Xcode/DerivedData/CashfreePgApiExample-gyturcincckczbfubbymyblkewhg/Build/Products/Debug-iphonesimulator/CashfreePgApiExample.app">
</PathRunnable>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
BuildableName = "CashfreePgApiExample.app"
BlueprintName = "CashfreePgApiExample"
ReferencedContainer = "container:CashfreePgApiExample.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</MacroExpansion>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
</plist>
2 changes: 1 addition & 1 deletion example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"@react-native-community/checkbox": "^0.5.16",
"react": "18.2.0",
"react-native": "0.72.4",
"react-native-cashfree-pg-sdk": "^2.1.12"
"react-native-cashfree-pg-sdk": "^2.1.12-dev.3"
},
"devDependencies": {
"@babel/core": "^7.20.0",
Expand Down
84 changes: 74 additions & 10 deletions example/App.js → example/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,28 @@
import * as React from 'react';
import { Component } from 'react';
import CheckBox from '@react-native-community/checkbox';
import { Button, Platform, ScrollView, StyleSheet, Text, TextInput, ToastAndroid, View } from 'react-native';
import { CFPaymentGatewayService } from 'react-native-cashfree-pg-sdk';
import { Card, CFCardPayment, CFDropCheckoutPayment, CFEnvironment, CFPaymentComponentBuilder, CFPaymentModes, CFSession, CFThemeBuilder, CFUPI, CFUPIIntentCheckoutPayment, CFUPIPayment, SavedCard, UPIMode, } from 'cashfree-pg-api-contract';
import { Button, Image, Platform, ScrollView, StyleSheet, Text, TextInput, ToastAndroid, View } from 'react-native';
import { CFPaymentGatewayService, CFCard } from 'react-native-cashfree-pg-sdk';
import { Card, CFCardPayment, CFDropCheckoutPayment, CFEnvironment, CFPaymentComponentBuilder, CFPaymentModes, CFSession, CFThemeBuilder, CFUPI, CFUPIIntentCheckoutPayment, CFUPIPayment, SavedCard, UPIMode, ElementCard } from 'cashfree-pg-api-contract';
const BASE_RESPONSE_TEXT = 'Payment Status will be shown here.';
export default class App extends Component {
constructor() {
super();
this.creditCardRef = React.createRef();
this.state = {
responseText: BASE_RESPONSE_TEXT,
cardNumber: '',
cardHolderName: '',
cardExpiryMM: '',
cardExpiryYY: '',
cardCVV: '',
orderId: '',
sessionId: '',
orderId: 'order_342fuAjbdkqC3DVHX18iy24dP4ArK',
sessionId: 'session_Ulz4xwKmTx-4nNZTIk40n5beAXmWxMiqegtqYMcgrdsqqaxnU0mqTa15NjkAlz1M4oJcwOGyjqNQCKTEhQZAm9ekeM4VIllrICSn4t80XI3o',
instrumentId: '',
toggleCheckBox: false,
cfEnv: '',
upiId: '',
cardNetwork: require('./assests/visa.png'),
};
}
updateStatus = (message) => {
Expand Down Expand Up @@ -61,6 +63,47 @@ export default class App extends Component {
handleUpi = (id) => {
this.setState({ upiId: id });
};
handleCFCardInput = (data) => {
console.log('CFCardInput FROM SDK', data);
const cardNetwork = JSON.parse(data)['card_network'];
switch (cardNetwork) {
case 'visa': {
this.setState({ cardNetwork: require('./assests/visa.png') });
break;
}
case 'mastercard': {
this.setState({ cardNetwork: require('./assests/mastercard.png') });
break;
}
case 'amex': {
this.setState({ cardNetwork: require('./assests/amex.png') });
break;
}
case 'maestro': {
this.setState({ cardNetwork: require('./assests/maestro.png') });
break;
}
case 'rupay': {
this.setState({ cardNetwork: require('./assests/rupay.png') });
break;
}
case 'diners': {
this.setState({ cardNetwork: require('./assests/diners.png') });
break;
}
case 'discover': {
this.setState({ cardNetwork: require('./assests/discover.png') });
break;
}
case 'jcb': {
this.setState({ cardNetwork: require('./assests/jcb.png') });
break;
}
default: {
this.setState({ cardNetwork: require('./assests/visa.png') });
}
}
};
componentWillUnmount() {
console.log('UNMOUNTED');
CFPaymentGatewayService.removeCallback();
Expand Down Expand Up @@ -204,7 +247,16 @@ export default class App extends Component {
getSession() {
return new CFSession(this.state.sessionId, this.state.orderId, this.state.cfEnv === 'PROD' ? CFEnvironment.PRODUCTION : CFEnvironment.SANDBOX);
}
handleSubmit = () => {
console.log('TYPE', this.creditCardRef);
if (this.creditCardRef.current) {
let nonPciCard = new ElementCard(this.state.cardHolderName, this.state.cardExpiryMM, this.state.cardExpiryYY, this.state.cardCVV, this.state.toggleCheckBox);
console.log('KISHANTEST', JSON.stringify(nonPciCard));
this.creditCardRef.current.doPayment(nonPciCard);
}
};
render() {
let cfCard = React.createElement(CFCard, { cfSession: this.getSession(), style: { flex: 1 }, cardListener: this.handleCFCardInput, placeholder: 'Enter Card Number', placeholderTextColor: '#0000ff', underlineColorAndroid: 'transparent', cursorColor: 'gray', returnKeyType: 'next', ref: this.creditCardRef, onSubmitEditing: (e) => console.log('onSubmitEditing', e.nativeEvent.text, '::', e.target.value), onEndEditing: (e) => console.log('onEndEditing', e.nativeEvent.text, '::', e.target.value), onBlur: (e) => console.log('onBlur', e.nativeEvent.text, '::', e.target.value), onFocus: (e) => console.log('onFocus', e.nativeEvent.text, '::', e.target.value), onSelectionchange: (e) => console.log('onSelectionchange', e.nativeEvent.text, '::', e.target.value), onKeyPress: (e) => console.log('onSelectionchange', e.nativeEvent.text, '::', e.target.value) });
return (React.createElement(ScrollView, null,
React.createElement(View, { style: styles.container },
React.createElement(View, { style: {
Expand Down Expand Up @@ -242,18 +294,22 @@ export default class App extends Component {
textAlign: 'center',
marginBottom: 10,
} },
React.createElement(View, { style: styles.cardContainer },
cfCard,
React.createElement(Image, { color: '#000', style: {
margin: 5,
}, source: this.state.cardNetwork })),
React.createElement(View, { style: { flexDirection: 'column', alignSelf: 'stretch', textAlign: 'center' } },
React.createElement(TextInput, { style: styles.input, placeholder: 'Card Number', keyboardType: 'numeric', maxLength: 16, onChangeText: this.handleCardNumber }),
React.createElement(TextInput, { style: styles.input, placeholder: 'Holder Name', keyboardType: 'default', onChangeText: this.handleCardHolderName })),
React.createElement(TextInput, { style: styles.input, placeholder: 'Holder Name', keyboardType: 'default', placeholderTextColor: '#0000ff', underlineColorAndroid: 'transparent', cursorColor: 'gray', onChangeText: this.handleCardHolderName })),
React.createElement(View, { style: { flexDirection: 'row', alignSelf: 'stretch' } },
React.createElement(TextInput, { style: styles.input, placeholder: 'Expiry Month', keyboardType: 'numeric', maxLength: 2, onChangeText: this.handleCardExpiryMM }),
React.createElement(TextInput, { style: styles.input, placeholder: 'Expiry Year', keyboardType: 'numeric', maxLength: 2, onChangeText: this.handleCardExpiryYY }),
React.createElement(TextInput, { style: styles.input, placeholder: 'Expiry Month', keyboardType: 'numeric', maxLength: 2, placeholderTextColor: '#0000ff', underlineColorAndroid: 'transparent', cursorColor: 'gray', onChangeText: this.handleCardExpiryMM }),
React.createElement(TextInput, { style: styles.input, placeholder: 'Expiry Year', keyboardType: 'numeric', maxLength: 2, placeholderTextColor: '#0000ff', underlineColorAndroid: 'transparent', cursorColor: 'gray', onChangeText: this.handleCardExpiryYY }),
React.createElement(TextInput, { style: styles.input, placeholder: 'CVV', keyboardType: 'numeric', maxLength: 3, secureTextEntry: true, onChangeText: this.handleCardCVV })),
React.createElement(View, { style: { flexDirection: 'row', alignSelf: 'stretch', alignItems: 'center', textAlign: 'center' } },
React.createElement(CheckBox, { value: this.state.toggleCheckBox, onValueChange: this.handleSaveCardToggle }),
React.createElement(Text, null, "Saved Card for future payment")),
React.createElement(View, { style: styles.button },
React.createElement(Button, { onPress: () => this._startCardPayment(), title: 'Card Payment' }))),
React.createElement(Button, { onPress: () => this.handleSubmit(), title: 'Card Payment' }))),
React.createElement(View, { style: {
borderWidth: 1,
alignSelf: 'stretch',
Expand Down Expand Up @@ -289,4 +345,12 @@ const styles = StyleSheet.create({
borderWidth: 1,
padding: 10,
},
cardContainer: {
flexDirection: 'row',
borderWidth: 1,
borderColor: '#000',
justifyContent: 'center',
alignItems: 'center',
margin: 10,
},
});
Loading

0 comments on commit a927fd7

Please sign in to comment.