Skip to content

Commit 32b56a3

Browse files
[CC-8193][8198] Add StoreCVN(Retokenization) Method (#97)
* add storeCVN method * added storeCVN test page * seperate tokenizationResponse with storeCVNResponse * update change log * bump sdk-version in build.gradle
1 parent e064352 commit 32b56a3

File tree

12 files changed

+369
-28
lines changed

12 files changed

+369
-28
lines changed

.idea/runConfigurations.xml

-12
This file was deleted.

CHANGELOG.md

+8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
# CHANGELOG
2+
3+
## 3.8.0 (2023-03-13)
4+
- Feat: Added storeCVN method for caching cvn on subsequent multi-use token purpose
5+
- Feat: Added storeCVN test page
6+
- Bug: Bug fix for validation on createAuthentication method
7+
8+
## NOTE: 3.4.2 - 3.7.0 is being skipped due to inconsistency github release tag version with sdk version. Starting on 3.8.0 these 2 version are sync.
9+
210
## 3.4.2 (2021-09-15)
311
- Updated Cardinal Commerce Library credentials
412

app/src/main/AndroidManifest.xml

+15-14
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3-
xmlns:tools="http://schemas.android.com/tools"
4-
package="com.xendit.example">
3+
xmlns:tools="http://schemas.android.com/tools"
4+
package="com.xendit.example">
55

6-
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
7-
<uses-permission android:name="android.permission.INTERNET"/>
6+
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
7+
<uses-permission android:name="android.permission.INTERNET" />
88
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
99
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
1010

11-
1211
<application
1312
android:allowBackup="true"
1413
android:icon="@mipmap/ic_launcher"
@@ -18,24 +17,26 @@
1817
android:theme="@style/AppTheme">
1918
<activity android:name="com.xendit.example.MainActivity">
2019
<intent-filter>
21-
<action android:name="android.intent.action.MAIN"/>
20+
<action android:name="android.intent.action.MAIN" />
2221

23-
<category android:name="android.intent.category.LAUNCHER"/>
22+
<category android:name="android.intent.category.LAUNCHER" />
2423
</intent-filter>
2524
</activity>
26-
2725
<activity
2826
android:name="com.xendit.example.CreateTokenActivity"
29-
android:theme="@style/AppTheme"/>
30-
27+
android:theme="@style/AppTheme" />
3128
<activity
3229
android:name="com.xendit.example.AuthenticationActivity"
33-
android:theme="@style/AppTheme"/>
34-
30+
android:theme="@style/AppTheme" />
3531
<activity
3632
android:name="com.xendit.example.ValidationUtilActivity"
37-
android:theme="@style/AppTheme"/>
33+
android:theme="@style/AppTheme" />
34+
<activity android:name="com.xendit.XenditActivity" />
3835

39-
<activity android:name="com.xendit.XenditActivity"/>
36+
<activity
37+
android:name=".StoreCvnActivity"
38+
android:theme="@style/AppTheme"
39+
/>
4040
</application>
41+
4142
</manifest>

app/src/main/java/com/xendit/example/MainActivity.java

+7
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
1414
private TextView authenticationTextView;
1515
private TextView validationUtilTextView;
1616

17+
private TextView storeCVNTextView;
18+
1719
@Override
1820
protected void onCreate(Bundle savedInstanceState) {
1921
super.onCreate(savedInstanceState);
@@ -24,9 +26,11 @@ protected void onCreate(Bundle savedInstanceState) {
2426
createTokenTextView = (TextView) findViewById(R.id.createTokenTextView_MainActivity);
2527
authenticationTextView = (TextView) findViewById(R.id.authenticationTextView_MainActivity);
2628
validationUtilTextView = (TextView) findViewById(R.id.validationUtilTextView_MainActivity);
29+
storeCVNTextView = (TextView) findViewById(R.id.storeCVNTextView_MainActivity);
2730

2831
createTokenTextView.setOnClickListener(this);
2932
authenticationTextView.setOnClickListener(this);
33+
storeCVNTextView.setOnClickListener(this);
3034
validationUtilTextView.setOnClickListener(this);
3135
}
3236

@@ -42,6 +46,9 @@ public void onClick(View view) {
4246
case R.id.validationUtilTextView_MainActivity:
4347
startActivity(ValidationUtilActivity.getLaunchIntent(this));
4448
break;
49+
case R.id.storeCVNTextView_MainActivity:
50+
startActivity(StoreCvnActivity.getLaunchIntent(this));
51+
break;
4552
}
4653
}
4754

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
package com.xendit.example;
2+
3+
import static com.xendit.example.CreateTokenActivity.PUBLISHABLE_KEY;
4+
5+
import android.content.Context;
6+
import android.content.Intent;
7+
import android.os.Bundle;
8+
import android.util.Log;
9+
import android.view.MenuItem;
10+
import android.view.View;
11+
import android.widget.Button;
12+
import android.widget.EditText;
13+
import android.widget.ProgressBar;
14+
import android.widget.TextView;
15+
import android.widget.Toast;
16+
17+
import androidx.appcompat.app.ActionBar;
18+
import androidx.appcompat.app.AppCompatActivity;
19+
20+
import com.google.gson.Gson;
21+
import com.xendit.Models.Address;
22+
import com.xendit.Models.BillingDetails;
23+
import com.xendit.Models.Customer;
24+
import com.xendit.Models.Token;
25+
import com.xendit.Models.XenditError;
26+
import com.xendit.Xendit;
27+
import com.xendit.example.models.StoreCVNResponse;
28+
import com.xendit.example.models.TokenizationResponse;
29+
import com.xendit.utils.StoreCVNCallback;
30+
31+
public class StoreCvnActivity extends AppCompatActivity implements View.OnClickListener {
32+
public static final String DUMMY_PUBLISHABLE_KEY = "xnd_public_development_O4uGfOR3gbOunJU4frcaHmLCYNLy8oQuknDm+R1r9G3S/b2lBQR+gQ==";
33+
34+
private EditText tokenId;
35+
private EditText cardCVN;
36+
private Button storeCVNBtn;
37+
private TextView storeCVNResult;
38+
39+
@Override
40+
protected void onCreate(Bundle savedInstanceState) {
41+
super.onCreate(savedInstanceState);
42+
setContentView(R.layout.activity_store_cvn);
43+
setActionBarTitle(getString(R.string.store_cvn));
44+
45+
// Bind UI Component to class fields
46+
tokenId = (EditText) findViewById(R.id.tokenIdEditText_StoreCVNActivity);
47+
cardCVN = (EditText) findViewById(R.id.cvnEditText_StoreCVNActivity);
48+
storeCVNBtn = (Button) findViewById(R.id.btnStoreCVN);
49+
storeCVNResult = (TextView) findViewById(R.id.result_storeCVNActivity);
50+
51+
storeCVNBtn.setOnClickListener(this);
52+
}
53+
54+
private void setActionBarTitle(String title) {
55+
ActionBar actionBar = getSupportActionBar();
56+
if (actionBar != null) {
57+
actionBar.setTitle(title);
58+
actionBar.setDisplayHomeAsUpEnabled(true);
59+
actionBar.setHomeButtonEnabled(true);
60+
}
61+
}
62+
63+
@Override
64+
public void onClick(View view) {
65+
final Xendit xendit = new Xendit(getApplicationContext(), DUMMY_PUBLISHABLE_KEY, this);
66+
67+
final ProgressBar progressBar = findViewById(R.id.progressBar);
68+
progressBar.setVisibility(View.VISIBLE);
69+
70+
// Dummy data
71+
Address billingAddress = new Address();
72+
billingAddress.setCountry("ID");
73+
billingAddress.setStreetLine1("Panglima Polim IV");
74+
billingAddress.setStreetLine2("Ruko Grand Panglima Polim, Blok E");
75+
billingAddress.setCity("Jakarta Selatan");
76+
billingAddress.setProvinceState("DKI Jakarta");
77+
billingAddress.setCategory("WORK");
78+
billingAddress.setPostalCode("123123");
79+
80+
BillingDetails billingDetails = new BillingDetails();
81+
billingDetails.setMobileNumber("+6208123123123");
82+
billingDetails.setEmail("[email protected]");
83+
billingDetails.setGivenNames("John");
84+
billingDetails.setSurname("Hudson");
85+
billingDetails.setPhoneNumber("+6208123123123");
86+
billingDetails.setAddress(billingAddress);
87+
88+
Address shippingAddress = billingAddress;
89+
Address[] customerAddress = { shippingAddress };
90+
91+
Customer customer = new Customer();
92+
customer.setMobileNumber("+6208123123123");
93+
customer.setEmail("[email protected]");
94+
customer.setGivenNames("John");
95+
customer.setSurname("Hudson");
96+
customer.setPhoneNumber("+6208123123123");
97+
customer.setNationality("ID");
98+
customer.setDateOfBirth("1990-04-13");
99+
customer.setDescription("test user");
100+
customer.setAddresses(customerAddress);
101+
102+
StoreCVNCallback callback = new StoreCVNCallback() {
103+
@Override
104+
public void onSuccess(Token token) {
105+
progressBar.setVisibility(View.GONE);
106+
Gson gson = new Gson();
107+
StoreCVNResponse storeCVNResponse = new StoreCVNResponse(token);
108+
String json = gson.toJson(storeCVNResponse);
109+
storeCVNResult.setText(json);
110+
Log.d("STORE_CVN_SUCCESS", json.toString());
111+
Toast.makeText(StoreCvnActivity.this, "Store CVN Successful", Toast.LENGTH_SHORT).show();
112+
}
113+
114+
@Override
115+
public void onError(XenditError xenditError) {
116+
progressBar.setVisibility(View.GONE);
117+
Log.d("STORE_CVN_FAILED", xenditError.toString());
118+
Toast.makeText(StoreCvnActivity.this, xenditError.getErrorCode() + " " +
119+
xenditError.getErrorMessage(), Toast.LENGTH_SHORT).show();
120+
}
121+
};
122+
123+
xendit.storeCVN(tokenId.getText().toString(), cardCVN.getText().toString(), billingDetails, customer, "", callback);
124+
}
125+
126+
@Override
127+
public boolean onOptionsItemSelected(MenuItem item) {
128+
switch (item.getItemId()) {
129+
case android.R.id.home:
130+
this.finish();
131+
return true;
132+
default:
133+
return super.onOptionsItemSelected(item);
134+
}
135+
}
136+
137+
public static Intent getLaunchIntent(Context context) {
138+
return new Intent(context, StoreCvnActivity.class);
139+
}
140+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.xendit.example.models;
2+
3+
import androidx.annotation.Keep;
4+
5+
import com.xendit.Models.CardInfo;
6+
import com.xendit.Models.Token;
7+
8+
@Keep
9+
public class StoreCVNResponse {
10+
private String id;
11+
private String authentication_id;
12+
private String status;
13+
private String masked_card_number;
14+
private CardInfo card_info;
15+
private String failure_reason;
16+
17+
public StoreCVNResponse(Token token) {
18+
id = token.getId();
19+
authentication_id = token.getAuthenticationId();
20+
status = token.getStatus();
21+
masked_card_number = token.getMaskedCardNumber();
22+
card_info = token.getCardInfo();
23+
failure_reason = token.getFailureReason();
24+
}
25+
}

app/src/main/res/layout/activity_main.xml

+10
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,16 @@
2424
android:textColor="@android:color/black"
2525
android:textSize="16sp"/>
2626

27+
<TextView
28+
android:id="@+id/storeCVNTextView_MainActivity"
29+
android:layout_width="match_parent"
30+
android:layout_height="wrap_content"
31+
android:gravity="center"
32+
android:padding="10dp"
33+
android:text="Retokenization for Store CVN"
34+
android:textColor="@android:color/black"
35+
android:textSize="16sp"/>
36+
2737
<TextView
2838
android:id="@+id/authenticationTextView_MainActivity"
2939
android:layout_width="match_parent"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:layout_width="match_parent"
4+
android:layout_height="match_parent"
5+
android:background="@android:color/white"
6+
android:orientation="vertical">
7+
8+
<TextView
9+
android:layout_width="100dp"
10+
android:layout_height="wrap_content"
11+
android:layout_marginStart="5dp"
12+
android:layout_marginLeft="5dp"
13+
android:text="TokenId"
14+
android:textSize="20sp"
15+
android:textColor="@android:color/black"/>
16+
17+
<EditText
18+
android:id="@+id/tokenIdEditText_StoreCVNActivity"
19+
android:text="640ec814c51ddd001a4f7e85"
20+
android:layout_width="wrap_content"
21+
android:layout_height="wrap_content"
22+
android:layout_marginStart="5dp"
23+
android:layout_marginLeft="5dp"
24+
android:hint="TokenId"
25+
android:textColor="@android:color/black"
26+
android:textColorHint="#cccccc" />
27+
28+
<TextView
29+
android:layout_width="100dp"
30+
android:layout_height="wrap_content"
31+
android:layout_marginStart="5dp"
32+
android:layout_marginLeft="5dp"
33+
android:text="Card CVN"
34+
android:textSize="20sp"
35+
android:textColor="@android:color/black"/>
36+
37+
<EditText
38+
android:id="@+id/cvnEditText_StoreCVNActivity"
39+
android:layout_width="wrap_content"
40+
android:layout_height="wrap_content"
41+
android:layout_marginStart="5dp"
42+
android:layout_marginLeft="5dp"
43+
android:hint="3-4 Digit Code"
44+
android:inputType="number"
45+
android:textColor="@android:color/black"
46+
android:textColorHint="#cccccc" />
47+
48+
<Button
49+
android:id="@+id/btnStoreCVN"
50+
android:layout_width="wrap_content"
51+
android:layout_height="wrap_content"
52+
android:layout_gravity="center"
53+
android:layout_marginTop="50dp"
54+
android:text="Store CVN" />
55+
56+
<TextView
57+
android:id="@+id/result_storeCVNActivity"
58+
android:layout_width="match_parent"
59+
android:layout_height="wrap_content"
60+
android:layout_margin="10dp"
61+
android:text=""
62+
android:textColor="@android:color/black"
63+
android:textIsSelectable="true"
64+
android:textSize="18sp" />
65+
66+
67+
<ProgressBar
68+
android:id="@+id/progressBar"
69+
android:layout_width="wrap_content"
70+
android:layout_height="wrap_content"
71+
android:layout_gravity="center"
72+
android:visibility="invisible"></ProgressBar>
73+
74+
</LinearLayout>

app/src/main/res/values/strings.xml

+1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@
55
<string name="cvnTest">123</string>
66
<string name="amountTest">123000</string>
77
<string name="create_token">Create Token</string>
8+
<string name="store_cvn">Store CVN</string>
89
</resources>

xendit-android/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ apply plugin: 'maven-publish'
33
apply plugin: 'com.jfrog.bintray'
44

55
group 'com.xendit'
6-
version '3.7.0'
6+
version '3.8.0'
77

88
ext {
99
bintrayOrg = 'xendit'

0 commit comments

Comments
 (0)