{"id":2666,"date":"2016-06-07T09:30:46","date_gmt":"2016-06-07T09:30:46","guid":{"rendered":"http:\/\/truelogic.org\/wordpress\/?p=2666"},"modified":"2016-06-16T05:50:46","modified_gmt":"2016-06-16T05:50:46","slug":"accepting-stripe-payments-in-android2","status":"publish","type":"post","link":"https:\/\/truelogic.org\/wordpress\/2016\/06\/07\/accepting-stripe-payments-in-android2\/","title":{"rendered":"Accepting Stripe Payments in Android"},"content":{"rendered":"            <script type=\"text\/javascript\" src=\"https:\/\/truelogic.org\/wordpress\/wp-content\/plugins\/wordpress-code-snippet\/scripts\/shBrushXml.js\"><\/script>\n            <script type=\"text\/javascript\" src=\"https:\/\/truelogic.org\/wordpress\/wp-content\/plugins\/wordpress-code-snippet\/scripts\/shBrushJava.js\"><\/script>\n<p>Stripe is one of the most widely used payment gateways currently. It is also one of the best for developers because it allows very easy and smooth integration of code in multiple languages. Here we are going to look at accepting stripe payments in an Android app.<\/p>\n<p>It is assumed that there is already a stripe account available for integration. If not then you can sign up for a free Stripe account and use it in test mode.<\/p>\n<h4>CONCEPTS<\/h4>\n<p>Before we look at the code, a few concepts need to be understood .<\/p>\n<p><strong>API Keys<\/strong><\/p>\n<p>Stripe can run in two modes &#8211; Live and Test mode. Test mode is useful while testing integration or for any scenario which allows you to test payment integration without actually charging live credit cards.\u00a0 When in test mode, Stripe has some predefined card numbers to use, as shown below. You can use these numbers with any CVC\/CVV number and any expiry month\/year set in the future.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-medium wp-image-2668\" src=\"https:\/\/truelogic.org\/wordpress\/wp-content\/uploads\/2016\/06\/testcard-620x372.png\" alt=\"testcard\" width=\"620\" height=\"372\" srcset=\"https:\/\/truelogic.org\/wordpress\/wp-content\/uploads\/2016\/06\/testcard-620x372.png 620w, https:\/\/truelogic.org\/wordpress\/wp-content\/uploads\/2016\/06\/testcard-300x180.png 300w, https:\/\/truelogic.org\/wordpress\/wp-content\/uploads\/2016\/06\/testcard.png 716w\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>For API integration, Stripe provides two keys &#8211; one Public and one Private. These can be found in your Stripe account settings. The Public key will have the prefix of <em>pk <\/em>and the Private Key will have the prefix of <em>sk <\/em>.\u00a0 You will have different pairs of Public\/Private keys for Test mode and Live Mode.<\/p>\n<p>So if you are going to use the Stripe gateway in Test mode then use the Test keys , otherwise use the Live keys.<\/p>\n<p><strong>Customer<\/strong><\/p>\n<p>A Customer Entity in Stripe is the person who makes payments into the account.<\/p>\n<p><strong>Card<\/strong><\/p>\n<p>A Card entity contains the credit card details of a Customer. A Customer may have multiple Cards.<\/p>\n<p><strong>Charge<\/strong><\/p>\n<p>An actual payment made in Stripe is called a Charge. A Charge is always linked to a Card and a Customer.<\/p>\n<p>There are more entities in Stripe like Subscription, Plans, Coupons etc. but here we are just dealing with a simple payment, so we will not look into the advanced concepts.<\/p>\n<h4>PROCESS<\/h4>\n<p>In the sample code, the following logic is in place.<\/p>\n<p>1.Create a Card entity in Stripe<\/p>\n<p>2.Create a Customer entity<\/p>\n<p>3.Create a Charge entity and link it with the Card and Customer entity.<\/p>\n<p>Each of these entities returns a unique id which has to be handled by your backend code. For instance, in your database you should store the Stripe customer id, so that the next time this customer does a payment you can retrieve the Customer Entity from Stripe and then do a Charge, instead of creating a duplicate Customer entity again.<\/p>\n<p>You can do a similar thing for the Card. A Card entity returns a Card token which can be stored and reused in your code. The advantage of this is that the actual card details are stored securely in Stripe and you can use the card token to tell Stripe which card to use.<\/p>\n<p>Note that amounts are to be sent in the lowest currency denomination. Eg. if you are using USD and the amount to be charged is $50.00 then the amount should not be sent to Stripe as 50.00 but 50*100 cents which is 5000 .<\/p>\n<pre><\/pre>\n<h4>THE APPLICATION<\/h4>\n<p>For your app to use the Stripe Android library, you need to link<\/p>\n<pre>'com.stripe:stripe-android'\r\n<\/pre>\n<p>This is shown in the build.gradle listing below.<\/p>\n<p>We have a single Activity screen which takes in the payment details, validates the data and then updates Stripe with the transaction details.<\/p>\n<p>&nbsp;<\/p>\n<h4>LISTINGS<\/h4>\n<p>&nbsp;<\/p>\n<p><strong>build.gradle<\/strong><br \/>\n<pre class=\"brush: xml\">apply plugin: &#039;com.android.application&#039;\r\n\r\nandroid {\r\n    compileSdkVersion 23\r\n    buildToolsVersion &quot;23.0.3&quot;\r\n\r\n    defaultConfig {\r\n        applicationId &quot;stripe.test.com.stripetest&quot;\r\n        minSdkVersion 19\r\n        targetSdkVersion 23\r\n        versionCode 1\r\n        versionName &quot;1.0&quot;\r\n    }\r\n    buildTypes {\r\n        release {\r\n            minifyEnabled false\r\n            proguardFiles getDefaultProguardFile(&#039;proguard-android.txt&#039;), &#039;proguard-rules.pro&#039;\r\n        }\r\n    }\r\n}\r\n\r\ndependencies {\r\n    compile fileTree(dir: &#039;libs&#039;, include: [&#039;*.jar&#039;])\r\n    testCompile &#039;junit:junit:4.12&#039;\r\n    compile &#039;com.android.support:appcompat-v7:23.4.0&#039;\r\n    compile &#039;com.android.support:design:23.4.0&#039;\r\n    compile &#039;com.stripe:stripe-android:+&#039;\r\n}\r\n<\/pre><\/p>\n<p><strong>Android.Manifest<\/strong><br \/>\n<pre class=\"brush: xml\">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;\r\n&lt;manifest xmlns:android=&quot;http:\/\/schemas.android.com\/apk\/res\/android&quot;\r\n    package=&quot;stripe.test.com.stripetest&quot;&gt;\r\n\r\n    &lt;uses-sdk\r\n        android:minSdkVersion=&quot;19&quot;\r\n        android:targetSdkVersion=&quot;23&quot; \/&gt;\r\n\r\n\r\n    &lt;uses-permission android:name=&quot;android.permission.INTERNET&quot; \/&gt;\r\n\r\n\r\n    &lt;application\r\n        android:allowBackup=&quot;true&quot;\r\n        android:icon=&quot;@mipmap\/ic_launcher&quot;\r\n        android:label=&quot;@string\/app_name&quot;\r\n        android:supportsRtl=&quot;true&quot;\r\n        android:theme=&quot;@style\/AppTheme&quot;&gt;\r\n        &lt;activity\r\n            android:name=&quot;.MainActivity&quot;\r\n            android:label=&quot;@string\/app_name&quot;\r\n            android:theme=&quot;@style\/AppTheme.NoActionBar&quot;&gt;\r\n            &lt;intent-filter&gt;\r\n                &lt;action android:name=&quot;android.intent.action.MAIN&quot; \/&gt;\r\n\r\n                &lt;category android:name=&quot;android.intent.category.LAUNCHER&quot; \/&gt;\r\n            &lt;\/intent-filter&gt;\r\n        &lt;\/activity&gt;\r\n    &lt;\/application&gt;\r\n\r\n&lt;\/manifest&gt;\r\n<\/pre><\/p>\n<p><strong>activity_main.xml<\/strong><br \/>\n<pre class=\"brush: xml\">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;\r\n&lt;LinearLayout xmlns:android=&quot;http:\/\/schemas.android.com\/apk\/res\/android&quot;\r\n    xmlns:app=&quot;http:\/\/schemas.android.com\/apk\/res-auto&quot;\r\n    xmlns:tools=&quot;http:\/\/schemas.android.com\/tools&quot;\r\n    android:layout_width=&quot;match_parent&quot;\r\n    android:layout_height=&quot;match_parent&quot;\r\n    android:paddingBottom=&quot;@dimen\/activity_vertical_margin&quot;\r\n    android:paddingLeft=&quot;@dimen\/activity_horizontal_margin&quot;\r\n    android:paddingRight=&quot;@dimen\/activity_horizontal_margin&quot;\r\n    android:paddingTop=&quot;@dimen\/activity_vertical_margin&quot;\r\n    app:layout_behavior=&quot;@string\/appbar_scrolling_view_behavior&quot;\r\n    android:orientation=&quot;vertical&quot;\r\n    tools:context=&quot;stripe.test.com.stripetest.MainActivity&quot;\r\n    &gt;\r\n\r\n\r\n\r\n    &lt;LinearLayout\r\n        android:layout_width=&quot;fill_parent&quot;\r\n        android:layout_height=&quot;wrap_content&quot;\r\n        android:orientation=&quot;horizontal&quot;\r\n        android:layout_marginBottom=&quot;10dp&quot;&gt;\r\n\r\n        &lt;TextView\r\n            android:id=&quot;@+id\/textStripeLabel&quot;\r\n            android:layout_width=&quot;0dp&quot;\r\n            android:layout_height=&quot;wrap_content&quot;\r\n            android:layout_weight=&quot;1&quot;\r\n            android:layout_gravity=&quot;center_horizontal&quot;\r\n            android:text=&quot;Transaction Details&quot;\r\n            android:textAllCaps=&quot;false&quot;\r\n            android:textAlignment=&quot;center&quot;\r\n            android:textSize=&quot;@dimen\/font_size_medium&quot;\r\n            android:textStyle=&quot;bold&quot;\r\n            \/&gt;\r\n\r\n\r\n    &lt;\/LinearLayout&gt;\r\n\r\n    &lt;LinearLayout\r\n        android:layout_width=&quot;fill_parent&quot;\r\n        android:layout_height=&quot;wrap_content&quot;\r\n        android:orientation=&quot;horizontal&quot;\r\n        android:background=&quot;@drawable\/sharp_rectangle_border&quot;\r\n        android:layout_marginBottom=&quot;20dp&quot;&gt;\r\n\r\n\r\n\r\n        &lt;EditText\r\n            android:id=&quot;@+id\/editStripeCardNumber1&quot;\r\n            android:layout_width=&quot;0dp&quot;\r\n            android:layout_height=&quot;wrap_content&quot;\r\n            android:layout_weight=&quot;0.20&quot;\r\n            android:padding=&quot;5dp&quot;\r\n            android:singleLine=&quot;true&quot;\r\n            android:hint=&quot;XXXX&quot;\r\n            android:inputType=&quot;number&quot;\r\n            android:maxLength=&quot;4&quot;\r\n            android:textColor=&quot;#000000&quot;\r\n            android:textCursorDrawable=&quot;@null&quot;\/&gt;\r\n\r\n        &lt;EditText\r\n            android:id=&quot;@+id\/editStripeCardNumber2&quot;\r\n            android:layout_width=&quot;0dp&quot;\r\n            android:layout_height=&quot;wrap_content&quot;\r\n            android:layout_weight=&quot;0.20&quot;\r\n            android:padding=&quot;5dp&quot;\r\n            android:singleLine=&quot;true&quot;\r\n            android:hint=&quot;XXXX&quot;\r\n            android:inputType=&quot;number&quot;\r\n            android:maxLength=&quot;4&quot;\r\n            android:textColor=&quot;#000000&quot;\r\n            android:textCursorDrawable=&quot;@null&quot;\/&gt;\r\n\r\n        &lt;EditText\r\n            android:id=&quot;@+id\/editStripeCardNumber3&quot;\r\n            android:layout_width=&quot;0dp&quot;\r\n            android:layout_height=&quot;wrap_content&quot;\r\n            android:layout_weight=&quot;0.20&quot;\r\n            android:padding=&quot;5dp&quot;\r\n            android:singleLine=&quot;true&quot;\r\n            android:hint=&quot;XXXX&quot;\r\n            android:inputType=&quot;number&quot;\r\n            android:maxLength=&quot;4&quot;\r\n            android:textColor=&quot;#000000&quot;\r\n            android:textCursorDrawable=&quot;@null&quot;\/&gt;\r\n\r\n        &lt;EditText\r\n            android:id=&quot;@+id\/editStripeCardNumber4&quot;\r\n            android:layout_width=&quot;0dp&quot;\r\n            android:layout_height=&quot;wrap_content&quot;\r\n            android:layout_weight=&quot;0.20&quot;\r\n            android:padding=&quot;5dp&quot;\r\n            android:singleLine=&quot;true&quot;\r\n            android:hint=&quot;XXXX&quot;\r\n            android:inputType=&quot;number&quot;\r\n            android:maxLength=&quot;4&quot;\r\n            android:textColor=&quot;#000000&quot;\r\n            android:textCursorDrawable=&quot;@null&quot;\/&gt;\r\n\r\n    &lt;\/LinearLayout&gt;\r\n\r\n    &lt;LinearLayout\r\n        android:layout_width=&quot;fill_parent&quot;\r\n        android:layout_height=&quot;wrap_content&quot;\r\n        android:orientation=&quot;horizontal&quot;\r\n        android:layout_marginBottom=&quot;20dp&quot;&gt;\r\n\r\n\r\n        &lt;EditText\r\n            android:id=&quot;@+id\/editStripeCVV&quot;\r\n            android:layout_width=&quot;0dp&quot;\r\n            android:layout_height=&quot;wrap_content&quot;\r\n            android:layout_weight=&quot;0.15&quot;\r\n            android:padding=&quot;5dp&quot;\r\n            android:hint=&quot;CVC&quot;\r\n            android:maxLength=&quot;3&quot;\r\n            android:singleLine=&quot;true&quot;\r\n            android:inputType=&quot;number&quot;\r\n            android:background=&quot;@drawable\/sharp_rectangle_border&quot;\r\n            android:textColor=&quot;#000000&quot;\r\n            android:layout_marginRight=&quot;10dp&quot;\r\n            android:textCursorDrawable=&quot;@null&quot;\/&gt;\r\n\r\n        &lt;LinearLayout\r\n            android:layout_width=&quot;0dp&quot;\r\n            android:layout_weight=&quot;0.80&quot;\r\n            android:layout_height=&quot;wrap_content&quot;\r\n            android:orientation=&quot;horizontal&quot;\r\n            android:padding=&quot;5dp&quot;\r\n            android:background=&quot;@drawable\/sharp_rectangle_border&quot;\r\n            &gt;\r\n\r\n            &lt;TextView\r\n                android:layout_width=&quot;0dp&quot;\r\n                android:layout_height=&quot;wrap_content&quot;\r\n                android:layout_weight=&quot;0.20&quot;\r\n                android:text=&quot;MM\/YYYY&quot;\r\n                android:textAllCaps=&quot;true&quot;\r\n                android:textSize=&quot;@dimen\/font_size_small&quot;\r\n                \/&gt;\r\n\r\n            &lt;Spinner\r\n                android:layout_width=&quot;0dp&quot;\r\n                android:padding=&quot;2dp&quot;\r\n                android:layout_height=&quot;wrap_content&quot;\r\n                android:layout_weight=&quot;0.25&quot;\r\n                android:id=&quot;@+id\/spinnerStripeExpMonth&quot;\r\n                android:layout_marginRight=&quot;5dp&quot;\r\n                \/&gt;\r\n\r\n            &lt;Spinner\r\n                android:layout_width=&quot;0dp&quot;\r\n                android:layout_height=&quot;wrap_content&quot;\r\n                android:layout_weight=&quot;0.25&quot;\r\n                android:padding=&quot;2dp&quot;\r\n\r\n                android:id=&quot;@+id\/spinnerStripeExpYear&quot;\r\n                \/&gt;\r\n        &lt;\/LinearLayout&gt;\r\n\r\n    &lt;\/LinearLayout&gt;\r\n\r\n\r\n    &lt;LinearLayout\r\n        android:layout_width=&quot;fill_parent&quot;\r\n        android:layout_height=&quot;wrap_content&quot;\r\n        android:orientation=&quot;horizontal&quot;\r\n        android:layout_marginBottom=&quot;10dp&quot;&gt;\r\n\r\n\r\n\r\n\r\n    &lt;\/LinearLayout&gt;\r\n\r\n    &lt;LinearLayout\r\n        android:layout_width=&quot;fill_parent&quot;\r\n        android:layout_height=&quot;wrap_content&quot;\r\n        android:orientation=&quot;horizontal&quot;\r\n        android:background=&quot;@drawable\/sharp_rectangle_border&quot;\r\n        android:layout_marginBottom=&quot;10dp&quot;&gt;\r\n\r\n        &lt;TextView\r\n            android:layout_width=&quot;0dp&quot;\r\n            android:layout_height=&quot;wrap_content&quot;\r\n            android:layout_weight=&quot;0.60&quot;\r\n            android:text=&quot;$&quot;\r\n            android:layout_gravity=&quot;end&quot;\r\n            android:textAlignment=&quot;textEnd&quot;\r\n            android:textSize=&quot;@dimen\/font_size_medium&quot;\r\n            android:textAllCaps=&quot;true&quot;\r\n\r\n            \/&gt;\r\n\r\n        &lt;EditText\r\n            android:id=&quot;@+id\/editStripeAmount&quot;\r\n            android:layout_width=&quot;0dp&quot;\r\n            android:layout_height=&quot;wrap_content&quot;\r\n            android:layout_weight=&quot;0.35&quot;\r\n            android:padding=&quot;2dp&quot;\r\n            android:editable=&quot;true&quot;\r\n            android:inputType=&quot;numberDecimal&quot;\r\n            android:singleLine=&quot;true&quot;\r\n            android:textAlignment=&quot;textEnd&quot;\r\n            android:textSize=&quot;@dimen\/font_size_medium&quot;\r\n            android:textColor=&quot;#000000&quot;\r\n            android:textCursorDrawable=&quot;@null&quot;\/&gt;\r\n    &lt;\/LinearLayout&gt;\r\n\r\n\r\n\r\n    &lt;LinearLayout\r\n        android:layout_width=&quot;fill_parent&quot;\r\n        android:layout_height=&quot;wrap_content&quot;\r\n        android:orientation=&quot;horizontal&quot;\r\n        android:layout_marginBottom=&quot;10dp&quot;&gt;\r\n\r\n\r\n\r\n        &lt;EditText\r\n            android:id=&quot;@+id\/editCustName&quot;\r\n            android:layout_width=&quot;0dp&quot;\r\n            android:layout_height=&quot;wrap_content&quot;\r\n            android:layout_weight=&quot;1&quot;\r\n            android:editable=&quot;true&quot;\r\n            android:singleLine=&quot;true&quot;\r\n            android:hint=&quot;Customer Name&quot;\r\n            android:textSize=&quot;@dimen\/font_size_small&quot;\r\n            android:textColor=&quot;#000000&quot;\r\n            android:textCursorDrawable=&quot;@null&quot;\/&gt;\r\n    &lt;\/LinearLayout&gt;\r\n\r\n\r\n    &lt;LinearLayout\r\n        android:layout_width=&quot;fill_parent&quot;\r\n        android:layout_height=&quot;wrap_content&quot;\r\n        android:orientation=&quot;horizontal&quot;\r\n        android:layout_marginBottom=&quot;10dp&quot;&gt;\r\n\r\n\r\n\r\n        &lt;EditText\r\n            android:id=&quot;@+id\/editCustEmail&quot;\r\n            android:layout_width=&quot;0dp&quot;\r\n            android:layout_height=&quot;wrap_content&quot;\r\n            android:layout_weight=&quot;1&quot;\r\n            android:editable=&quot;true&quot;\r\n            android:inputType=&quot;textEmailAddress&quot;\r\n            android:singleLine=&quot;true&quot;\r\n            android:hint=&quot;Customer Email&quot;\r\n            android:textSize=&quot;@dimen\/font_size_small&quot;\r\n            android:textColor=&quot;#000000&quot;\r\n            android:textCursorDrawable=&quot;@null&quot;\/&gt;\r\n    &lt;\/LinearLayout&gt;\r\n\r\n\r\n    &lt;LinearLayout\r\n        android:layout_width=&quot;fill_parent&quot;\r\n        android:layout_height=&quot;wrap_content&quot;\r\n        android:orientation=&quot;horizontal&quot;\r\n        android:layout_marginBottom=&quot;10dp&quot;&gt;\r\n\r\n\r\n\r\n        &lt;EditText\r\n            android:id=&quot;@+id\/editCustAddress&quot;\r\n            android:layout_width=&quot;0dp&quot;\r\n            android:layout_height=&quot;wrap_content&quot;\r\n            android:layout_weight=&quot;1&quot;\r\n            android:editable=&quot;true&quot;\r\n            android:singleLine=&quot;true&quot;\r\n            android:hint=&quot;Customer Address&quot;\r\n            android:textSize=&quot;@dimen\/font_size_small&quot;\r\n            android:textColor=&quot;#000000&quot;\r\n            android:textCursorDrawable=&quot;@null&quot;\/&gt;\r\n    &lt;\/LinearLayout&gt;\r\n\r\n    &lt;LinearLayout\r\n        android:layout_width=&quot;fill_parent&quot;\r\n        android:layout_height=&quot;wrap_content&quot;\r\n        android:orientation=&quot;horizontal&quot;\r\n        android:layout_marginBottom=&quot;10dp&quot;&gt;\r\n\r\n\r\n\r\n\r\n    &lt;\/LinearLayout&gt;\r\n\r\n\r\n    &lt;LinearLayout\r\n        android:layout_width=&quot;fill_parent&quot;\r\n        android:layout_height=&quot;wrap_content&quot;\r\n        android:orientation=&quot;horizontal&quot;\r\n        android:layout_marginTop=&quot;5dp&quot;&gt;\r\n        &lt;Button\r\n            style=&quot;?android:attr\/buttonStyleSmall&quot;\r\n            android:layout_width=&quot;wrap_content&quot;\r\n            android:layout_height=&quot;wrap_content&quot;\r\n            android:text=&quot;Cancel&quot;\r\n            android:id=&quot;@+id\/btnStripeCancel&quot;\r\n            android:layout_weight=&quot;0.45&quot;\r\n            android:onClick=&quot;showInvoices&quot;\r\n            \/&gt;\r\n\r\n\r\n\r\n        &lt;View\r\n            android:layout_width=&quot;0dp&quot;\r\n            android:layout_height=&quot;0dp&quot;\r\n            android:layout_weight=&quot;0.10&quot; \/&gt;\r\n\r\n        &lt;Button\r\n            style=&quot;?android:attr\/buttonStyleSmall&quot;\r\n            android:layout_width=&quot;wrap_content&quot;\r\n            android:layout_height=&quot;wrap_content&quot;\r\n            android:text=&quot;Save&quot;\r\n            android:id=&quot;@+id\/btnStripeSave&quot;\r\n            android:layout_weight=&quot;0.45&quot;\r\n            android:onClick=&quot;doPayment&quot;\r\n            \/&gt;\r\n\r\n\r\n    &lt;\/LinearLayout&gt;\r\n\r\n    &lt;LinearLayout\r\n        android:layout_width=&quot;fill_parent&quot;\r\n        android:layout_height=&quot;wrap_content&quot;\r\n        android:orientation=&quot;horizontal&quot;\r\n        android:layout_marginBottom=&quot;10dp&quot;&gt;\r\n\r\n        &lt;TextView\r\n            android:id=&quot;@+id\/textStripeMode&quot;\r\n            android:layout_width=&quot;0dp&quot;\r\n            android:layout_height=&quot;wrap_content&quot;\r\n            android:layout_weight=&quot;1&quot;\r\n            android:layout_gravity=&quot;center_horizontal&quot;\r\n            android:text=&quot;&quot;\r\n            android:textAllCaps=&quot;true&quot;\r\n            android:textAlignment=&quot;center&quot;\r\n            android:textSize=&quot;@dimen\/font_size_small&quot;\r\n            \/&gt;\r\n\r\n\r\n    &lt;\/LinearLayout&gt;\r\n\r\n&lt;\/LinearLayout&gt;\r\n<\/pre><\/p>\n<p><strong>drawable\/sharp_rectangle_border.xml<\/strong><br \/>\n<pre class=\"brush: xml\">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;\r\n&lt;layer-list xmlns:android=&quot;http:\/\/schemas.android.com\/apk\/res\/android&quot;&gt;\r\n    &lt;item&gt;\r\n        &lt;shape android:shape=&quot;rectangle&quot;&gt;\r\n            &lt;solid android:color=&quot;#d4d4d4&quot;\/&gt;\r\n            &lt;corners android:radius=&quot;0dp&quot; \/&gt;\r\n        &lt;\/shape&gt;\r\n    &lt;\/item&gt;\r\n\r\n    &lt;item\r\n        android:left=&quot;1dp&quot;\r\n        android:right=&quot;1dp&quot;\r\n        android:top=&quot;1dp&quot;\r\n        android:bottom=&quot;1dp&quot;&gt;\r\n        &lt;shape android:shape=&quot;rectangle&quot;&gt;\r\n            &lt;solid android:color=&quot;@android:color\/white&quot;\/&gt;\r\n            &lt;corners android:radius=&quot;0dp&quot; \/&gt;\r\n        &lt;\/shape&gt;\r\n    &lt;\/item&gt;\r\n&lt;\/layer-list&gt;<\/pre><\/p>\n<p><strong>values\/dimens.xml<\/strong><br \/>\n<pre class=\"brush: xml\">&lt;resources&gt;\r\n    &lt;!-- Default screen margins, per the Android Design guidelines. --&gt;\r\n    &lt;dimen name=&quot;activity_horizontal_margin&quot;&gt;16dp&lt;\/dimen&gt;\r\n    &lt;dimen name=&quot;activity_vertical_margin&quot;&gt;16dp&lt;\/dimen&gt;\r\n\r\n    &lt;!-- Per the design guidelines, navigation drawers should be between 240dp and 320dp:\r\n       https:\/\/developer.android.com\/design\/patterns\/navigation-drawer.html --&gt;\r\n    &lt;dimen name=&quot;navigation_drawer_width&quot;&gt;240dp&lt;\/dimen&gt;\r\n\r\n    &lt;dimen name=&quot;font_size_verysmall&quot;&gt;10sp&lt;\/dimen&gt;\r\n    &lt;dimen name=&quot;font_size_small&quot;&gt;12sp&lt;\/dimen&gt;\r\n    &lt;dimen name=&quot;font_size_average&quot;&gt;14sp&lt;\/dimen&gt;\r\n    &lt;dimen name=&quot;font_size_medium&quot;&gt;20sp&lt;\/dimen&gt;\r\n    &lt;dimen name=&quot;font_size_large&quot;&gt;30sp&lt;\/dimen&gt;\r\n    &lt;dimen name=&quot;font_size_verylarge&quot;&gt;50sp&lt;\/dimen&gt;\r\n\r\n\r\n\r\n&lt;\/resources&gt;\r\n<\/pre><\/p>\n<p><strong>MainActivity.java<\/strong><br \/>\n<pre class=\"brush: java\">package stripe.test.com.stripetest;\r\n\r\nimport android.app.ProgressDialog;\r\nimport android.os.AsyncTask;\r\nimport android.os.Bundle;\r\nimport android.support.design.widget.FloatingActionButton;\r\nimport android.support.design.widget.Snackbar;\r\nimport android.support.v7.app.AppCompatActivity;\r\nimport android.support.v7.widget.Toolbar;\r\nimport android.text.Editable;\r\nimport android.text.TextWatcher;\r\nimport android.view.View;\r\nimport android.view.Menu;\r\nimport android.view.MenuItem;\r\nimport android.widget.ArrayAdapter;\r\nimport android.widget.EditText;\r\nimport android.widget.Spinner;\r\nimport android.widget.Toast;\r\n\r\nimport com.stripe.android.Stripe;\r\nimport com.stripe.android.TokenCallback;\r\nimport com.stripe.android.model.Card;\r\nimport com.stripe.android.model.Token;\r\nimport com.stripe.exception.AuthenticationException;\r\nimport com.stripe.exception.CardException;\r\nimport com.stripe.model.Charge;\r\nimport com.stripe.model.Customer;\r\nimport com.stripe.net.RequestOptions;\r\n\r\nimport java.math.BigDecimal;\r\nimport java.text.DecimalFormat;\r\nimport java.text.SimpleDateFormat;\r\nimport java.util.Calendar;\r\nimport java.util.HashMap;\r\nimport java.util.Map;\r\n\r\npublic class MainActivity extends AppCompatActivity {\r\n\r\n    ProgressDialog mProgressBar;\r\n    private String mStripeCardToken;\r\n    private String mPublicKey = &quot;&quot;;\r\n    private String mPrivateKey = &quot;&quot;;\r\n\r\n    private Token mToken;\r\n    private Stripe mStripe = null;\r\n    private String mStripeCustId;\r\n    private boolean mCustWasAdded = false;\r\n    private String mCustomerName;\r\n    private String mCustomerEmail;\r\n    private String mCustomerAddress;\r\n    private BigDecimal mAmount;\r\n    private String mTxnRef;\r\n\r\n\r\n    @Override\r\n    protected void onCreate(Bundle savedInstanceState) {\r\n        super.onCreate(savedInstanceState);\r\n        setContentView(R.layout.activity_main);\r\n\r\n        mProgressBar = new ProgressDialog(this);\r\n\r\n        \/\/ populate spinners\r\n        String []months = new String[12];\r\n        for (int i =1;  i &lt;=12; i++) {\r\n            String val = &quot;&quot;;\r\n            if (i &lt; 10)\r\n                val = &quot;0&quot;;\r\n            months[i-1] = val + String.valueOf(i);\r\n        }\r\n        Spinner s = (Spinner) findViewById(R.id.spinnerStripeExpMonth);\r\n        ArrayAdapter&lt;String&gt; adapter = new ArrayAdapter&lt;String&gt;(this,\r\n                android.R.layout.simple_spinner_item, months);\r\n        s.setAdapter(adapter);\r\n\r\n        String []years = new String[12];\r\n        for (int i =1;  i &lt;=12; i++) {\r\n            years[i-1] = String.valueOf(i+2015);\r\n        }\r\n        Spinner s2 = (Spinner) findViewById(R.id.spinnerStripeExpYear);\r\n        ArrayAdapter&lt;String&gt; adapter2 = new ArrayAdapter&lt;String&gt;(this,\r\n                android.R.layout.simple_spinner_item, years);\r\n        s2.setAdapter(adapter2);\r\n\r\n\r\n        \/\/ set auto jump to next field for CC entry\r\n        EditText card1 = (EditText)findViewById(R.id.editStripeCardNumber1);\r\n        card1.addTextChangedListener(new TextWatcher() {\r\n            @Override\r\n            public void beforeTextChanged(CharSequence s, int start, int count, int after) {\r\n\r\n            }\r\n\r\n            @Override\r\n            public void onTextChanged(CharSequence s, int start, int before, int count) {\r\n\r\n            }\r\n\r\n            @Override\r\n            public void afterTextChanged(Editable s) {\r\n                EditText card1 = (EditText) findViewById(R.id.editStripeCardNumber1);\r\n                if (card1.getText().toString().length() == 4) {\r\n                    EditText card2 = (EditText) findViewById(R.id.editStripeCardNumber2);\r\n                    card2.requestFocus();\r\n                }\r\n\r\n            }\r\n        });\r\n\r\n        EditText card2 = (EditText)findViewById(R.id.editStripeCardNumber2);\r\n        card2.addTextChangedListener(new TextWatcher() {\r\n            @Override\r\n            public void beforeTextChanged(CharSequence s, int start, int count, int after) {\r\n\r\n            }\r\n\r\n            @Override\r\n            public void onTextChanged(CharSequence s, int start, int before, int count) {\r\n\r\n            }\r\n\r\n            @Override\r\n            public void afterTextChanged(Editable s) {\r\n                EditText card2 = (EditText)findViewById(R.id.editStripeCardNumber2);\r\n                if (card2.getText().toString().length() == 4) {\r\n                    EditText card3 = (EditText)findViewById(R.id.editStripeCardNumber3);\r\n                    card3.requestFocus();\r\n                }\r\n\r\n            }\r\n        });\r\n\r\n        EditText card3 = (EditText)findViewById(R.id.editStripeCardNumber3);\r\n        card3.addTextChangedListener(new TextWatcher() {\r\n            @Override\r\n            public void beforeTextChanged(CharSequence s, int start, int count, int after) {\r\n\r\n            }\r\n\r\n            @Override\r\n            public void onTextChanged(CharSequence s, int start, int before, int count) {\r\n\r\n            }\r\n\r\n            @Override\r\n            public void afterTextChanged(Editable s) {\r\n                EditText card3 = (EditText) findViewById(R.id.editStripeCardNumber3);\r\n                if (card3.getText().toString().length() == 4) {\r\n                    EditText card4 = (EditText) findViewById(R.id.editStripeCardNumber4);\r\n                    card4.requestFocus();\r\n                }\r\n\r\n            }\r\n        });\r\n\r\n        \/\/ set stripe key values\r\n        \/\/ this info would actually come from another place in the app or from the backend. I am just putting hardcoded values here\r\n        mPublicKey = &quot;pk_test_apikey_comes_here&quot;;\r\n        mPrivateKey = &quot;sk_test_apikey_comes_here&quot;;\r\n\r\n        \/\/ if you already have the customer details and have his stripe customer id, then this is the time to retrieve and\r\n        \/\/ assign it to mStripeCustId\r\n\r\n\r\n\r\n    }\r\n\r\n    @Override\r\n    public boolean onCreateOptionsMenu(Menu menu) {\r\n        \/\/ Inflate the menu; this adds items to the action bar if it is present.\r\n        getMenuInflater().inflate(R.menu.menu_main, menu);\r\n        return true;\r\n    }\r\n\r\n    @Override\r\n    public boolean onOptionsItemSelected(MenuItem item) {\r\n        \/\/ Handle action bar item clicks here. The action bar will\r\n        \/\/ automatically handle clicks on the Home\/Up button, so long\r\n        \/\/ as you specify a parent activity in AndroidManifest.xml.\r\n        int id = item.getItemId();\r\n\r\n        \/\/noinspection SimplifiableIfStatement\r\n        if (id == R.id.action_settings) {\r\n            return true;\r\n        }\r\n\r\n        return super.onOptionsItemSelected(item);\r\n    }\r\n\r\n    public void doPayment(View view) {\r\n        boolean isValid = true;\r\n\r\n\r\n        Spinner s = (Spinner) findViewById(R.id.spinnerStripeExpMonth);\r\n        Spinner s2 = (Spinner) findViewById(R.id.spinnerStripeExpYear);\r\n\r\n        String cardNumber = &quot;&quot;;\r\n        EditText textCard1 = (EditText) findViewById(R.id.editStripeCardNumber1);\r\n        EditText textCard2 = (EditText) findViewById(R.id.editStripeCardNumber2);\r\n        EditText textCard3 = (EditText) findViewById(R.id.editStripeCardNumber3);\r\n        EditText textCard4 = (EditText) findViewById(R.id.editStripeCardNumber4);\r\n        cardNumber = textCard1.getText().toString();\r\n        cardNumber += textCard2.getText().toString();\r\n        cardNumber += textCard3.getText().toString();\r\n        cardNumber += textCard4.getText().toString();\r\n\r\n\r\n        EditText textAmount = (EditText) findViewById(R.id.editStripeAmount);\r\n        EditText textName = (EditText) findViewById(R.id.editCustName);\r\n        EditText textEmail = (EditText) findViewById(R.id.editCustEmail);\r\n        EditText textAddress = (EditText) findViewById(R.id.editCustAddress);\r\n\r\n        try {\r\n            mAmount = new BigDecimal(Double.parseDouble(textAmount.getText().toString()));\r\n\r\n        } catch (NumberFormatException nex) {\r\n            Toast.makeText(getApplicationContext(), &quot;Invalid amount entered&quot;, Toast.LENGTH_LONG).show();\r\n            isValid = false;\r\n            return;\r\n        }\r\n\r\n        if (cardNumber.length() &lt; 16) {\r\n            Toast.makeText(getApplicationContext(), &quot;Card number looks invalid&quot;, Toast.LENGTH_LONG).show();\r\n            isValid = false;\r\n            return;\r\n        }\r\n\r\n        EditText textCVV = (EditText) findViewById(R.id.editStripeCVV);\r\n        if (textCVV.getText().toString().length() &lt; 3) {\r\n            Toast.makeText(getApplicationContext(), &quot;CVC looks invalid&quot;, Toast.LENGTH_LONG).show();\r\n            isValid = false;\r\n            return;\r\n        }\r\n\r\n        int month = Integer.parseInt(s.getSelectedItem().toString());\r\n        int year = Integer.parseInt(s2.getSelectedItem().toString());\r\n\r\n        Card card = new Card(cardNumber, month, year, textCVV.getText().toString());\r\n\r\n\r\n        if ( !card.validateCard() ) {\r\n\r\n            Toast.makeText(getApplicationContext(), &quot;Credit card validation failed!&quot;, Toast.LENGTH_LONG).show();\r\n            isValid = false;\r\n            return;\r\n        }\r\n\r\n        mCustomerAddress = textAddress.getText().toString();\r\n        mCustomerEmail = textEmail.getText().toString();\r\n        mCustomerName = textName.getText().toString();\r\n\r\n\r\n\r\n        mProgressBar.setCancelable(false);\r\n        mProgressBar.setMessage(&quot;Validating payment..&quot;);\r\n        mProgressBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);\r\n        mProgressBar.show();\r\n\r\n        if (mStripeCardToken == null || mStripeCardToken.equals(&quot;&quot;)) {\r\n            try {\r\n                mStripe = new Stripe(mPublicKey);\r\n                mStripe.createToken(\r\n                        card,\r\n                        new TokenCallback() {\r\n                            public void onSuccess(Token token) {\r\n                                mProgressBar.hide();\r\n                                mToken = token;\r\n\r\n                                mStripeCardToken = mToken.getId();\r\n                                checkCustomerStatus();\r\n\r\n\r\n                            }\r\n\r\n                            public void onError(Exception error) {\r\n                                mProgressBar.hide();\r\n                                \/\/ Show localized error message\r\n                                Toast.makeText(getApplicationContext(),\r\n                                        error.getMessage(),\r\n                                        Toast.LENGTH_LONG\r\n                                ).show();\r\n                                return;\r\n                            }\r\n                        }\r\n                );\r\n\r\n            } catch (AuthenticationException aex) {\r\n                Toast.makeText(getApplicationContext(), aex.getMessage(), Toast.LENGTH_LONG).show();\r\n            }\r\n        } else {\r\n\r\n            checkCustomerStatus();\r\n        }\r\n\r\n\r\n    }\r\n\r\n    void checkCustomerStatus() {\r\n\r\n        if (mStripeCustId == null || mStripeCustId.equals(&quot;&quot;)) {\r\n\r\n            mProgressBar.setCancelable(false);\r\n            mProgressBar.setMessage(&quot;Adding customer to stripe account..&quot;);\r\n            mProgressBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);\r\n            mProgressBar.show();\r\n\r\n            new CheckCustomerTask().execute(0);\r\n        } else {\r\n\r\n            chargeTransaction();\r\n        }\r\n    }\r\n\r\n    private void chargeTransaction() {\r\n        mProgressBar.setCancelable(false);\r\n        mProgressBar.setMessage(&quot;Charging credit card..&quot;);\r\n        mProgressBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);\r\n        mProgressBar.show();\r\n\r\n        new MakeChargeTask().execute(0);\r\n\r\n    }\r\n\r\n    public void savePayment() {\r\n        \/\/ this is where you update the payment to your backend servers or database\r\n        \/\/ and then take the user to the next screen\r\n\r\n        Toast.makeText(getApplicationContext(), &quot;Payment has been updated.&quot;, Toast.LENGTH_LONG).show();\r\n    }\r\n\r\n    public void updateCustomer() {\r\n\r\n        mProgressBar.setCancelable(false);\r\n        mProgressBar.setMessage(&quot;Updating customer details..&quot;);\r\n        mProgressBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);\r\n        mProgressBar.show();\r\n        new UpdateCustomerTask().execute(0);\r\n\r\n\r\n    }\r\n\r\n    \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\r\n\r\n    \/\/\r\n    \/\/ The params are dummy and not used\r\n    \/\/\r\n    class UpdateCustomerTask extends AsyncTask&lt;Integer, Integer, String&gt; {\r\n        String mError = null;\r\n\r\n        @Override\r\n        protected String doInBackground(Integer... params) {\r\n\r\n            try {\r\n                    \/\/ update the customer data in your backend or database\r\n\r\n                Thread.sleep(200);\r\n\r\n            } catch (InterruptedException iex) {}\r\n\r\n            return &quot;Task Completed.&quot;;\r\n        }\r\n        @Override\r\n        protected void onPostExecute(String result) {\r\n            mProgressBar.hide();\r\n            if (mError != null &amp;&amp; mError != &quot;&quot;)\r\n                Toast.makeText(getApplicationContext(), mError, Toast.LENGTH_LONG).show();\r\n            else {\r\n                chargeTransaction();\r\n            }\r\n        }\r\n        @Override\r\n        protected void onPreExecute() {\r\n        }\r\n        @Override\r\n        protected void onProgressUpdate(Integer... values) {\r\n\r\n        }\r\n    }\r\n\r\n\r\n    \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\r\n\r\n    \/\/\r\n    \/\/ The params are dummy and not used\r\n    \/\/\r\n    class CheckCustomerTask extends AsyncTask&lt;Integer, Integer, String&gt; {\r\n        String mError = null;\r\n\r\n        @Override\r\n        protected String doInBackground(Integer... params) {\r\n            String mError = &quot;&quot;;\r\n\r\n            try {\r\n                if (mStripe == null)\r\n                    mStripe = new Stripe(mPublicKey);\r\n                RequestOptions requestOptions = (new RequestOptions.RequestOptionsBuilder()).setApiKey(mPrivateKey).build();\r\n\r\n                Map&lt;String, Object&gt; customerParams = new HashMap&lt;String, Object&gt;();\r\n                customerParams.put(&quot;description&quot;, mCustomerName);\r\n                customerParams.put(&quot;email&quot;, mCustomerEmail);\r\n                customerParams.put(&quot;source&quot;, mStripeCardToken); \/\/ obtained with Stripe\r\n\r\n                Customer cust = Customer.create(customerParams, requestOptions);\r\n                mCustWasAdded = true;\r\n\r\n                mStripeCustId = cust.getId();\r\n\r\n\r\n            } catch (Exception cx) {\r\n                mError = cx.getMessage();\r\n\r\n            }\r\n\r\n            return &quot;Task Completed.&quot;;\r\n        }\r\n        @Override\r\n        protected void onPostExecute(String result) {\r\n            mProgressBar.hide();\r\n            if (mError != null &amp;&amp; mError != &quot;&quot;)\r\n                Toast.makeText(getApplicationContext(), mError, Toast.LENGTH_LONG).show();\r\n            else {\r\n                if (mCustWasAdded)\r\n                    updateCustomer();\r\n                else\r\n                    chargeTransaction();\r\n            }\r\n        }\r\n        @Override\r\n        protected void onPreExecute() {\r\n        }\r\n        @Override\r\n        protected void onProgressUpdate(Integer... values) {\r\n\r\n        }\r\n    }\r\n\r\n    \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\r\n\r\n    \/\/\r\n    \/\/ The params are dummy and not used\r\n    \/\/\r\n    class MakeChargeTask extends AsyncTask&lt;Integer, Integer, String&gt; {\r\n        String mError = null;\r\n\r\n        @Override\r\n        protected String doInBackground(Integer... params) {\r\n\r\n            DecimalFormat decimalFormat = new DecimalFormat(&quot;0.00&quot;);\r\n            String sAmount = decimalFormat.format(mAmount);\r\n            sAmount = sAmount.replace(&quot;.&quot;, &quot;&quot;);\r\n\r\n\r\n            \/\/ Create the charge on Stripe&#039;s servers - this will charge the user&#039;s card\r\n            try {\r\n                if (mStripe == null)\r\n                    mStripe = new Stripe(mPublicKey);\r\n                RequestOptions requestOptions = (new RequestOptions.RequestOptionsBuilder()).setApiKey(mPrivateKey).build();\r\n\r\n                Map&lt;String, Object&gt; chargeParams = new HashMap&lt;String, Object&gt;();\r\n                chargeParams.put(&quot;amount&quot;, Integer.parseInt(sAmount)); \/\/ amount in cents, again\r\n                chargeParams.put(&quot;currency&quot;, &quot;usd&quot;);\r\n                chargeParams.put(&quot;customer&quot;, mStripeCustId);\r\n                chargeParams.put(&quot;description&quot;, &quot;Payment description will come here&quot;);\r\n\r\n\r\n                Charge charge = Charge.create(chargeParams, requestOptions);\r\n                mTxnRef = charge.getId();\r\n\r\n\r\n\r\n\r\n            } catch (Exception e) {\r\n                \/\/ The card has been declined\r\n                mError = e.getMessage();\r\n            }\r\n\r\n            return &quot;Task Completed.&quot;;\r\n        }\r\n        @Override\r\n        protected void onPostExecute(String result) {\r\n            mProgressBar.hide();\r\n            if (mError != null &amp;&amp; mError != &quot;&quot;)\r\n                Toast.makeText(getApplicationContext(), mError, Toast.LENGTH_LONG).show();\r\n            else {\r\n                savePayment();\r\n            }\r\n        }\r\n        @Override\r\n        protected void onPreExecute() {\r\n        }\r\n        @Override\r\n        protected void onProgressUpdate(Integer... values) {\r\n\r\n        }\r\n    }\r\n\r\n}\r\n<\/pre><\/p>\n<h4>SCREENSHOTS<\/h4>\n<p><strong>App Screen<\/strong><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-2676\" src=\"https:\/\/truelogic.org\/wordpress\/wp-content\/uploads\/2016\/06\/Screenshot_2016-06-07-13-35-59.png\" alt=\"Screenshot_2016-06-07-13-35-59\" width=\"480\" height=\"854\" srcset=\"https:\/\/truelogic.org\/wordpress\/wp-content\/uploads\/2016\/06\/Screenshot_2016-06-07-13-35-59.png 480w, https:\/\/truelogic.org\/wordpress\/wp-content\/uploads\/2016\/06\/Screenshot_2016-06-07-13-35-59-300x534.png 300w\" sizes=\"auto, (max-width: 480px) 100vw, 480px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Stripe Transaction Details<\/strong><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-medium wp-image-2677\" src=\"https:\/\/truelogic.org\/wordpress\/wp-content\/uploads\/2016\/06\/stripe1-620x749.png\" alt=\"stripe1\" width=\"620\" height=\"749\" srcset=\"https:\/\/truelogic.org\/wordpress\/wp-content\/uploads\/2016\/06\/stripe1-620x749.png 620w, https:\/\/truelogic.org\/wordpress\/wp-content\/uploads\/2016\/06\/stripe1-300x362.png 300w, https:\/\/truelogic.org\/wordpress\/wp-content\/uploads\/2016\/06\/stripe1-768x927.png 768w, https:\/\/truelogic.org\/wordpress\/wp-content\/uploads\/2016\/06\/stripe1-940x1135.png 940w, https:\/\/truelogic.org\/wordpress\/wp-content\/uploads\/2016\/06\/stripe1.png 1239w\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Stripe Customer Details<\/strong><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-medium wp-image-2678\" src=\"https:\/\/truelogic.org\/wordpress\/wp-content\/uploads\/2016\/06\/stripe2-620x1070.png\" alt=\"stripe2\" width=\"620\" height=\"1070\" srcset=\"https:\/\/truelogic.org\/wordpress\/wp-content\/uploads\/2016\/06\/stripe2-620x1070.png 620w, https:\/\/truelogic.org\/wordpress\/wp-content\/uploads\/2016\/06\/stripe2-300x518.png 300w, https:\/\/truelogic.org\/wordpress\/wp-content\/uploads\/2016\/06\/stripe2-768x1325.png 768w, https:\/\/truelogic.org\/wordpress\/wp-content\/uploads\/2016\/06\/stripe2-940x1622.png 940w, https:\/\/truelogic.org\/wordpress\/wp-content\/uploads\/2016\/06\/stripe2.png 1239w\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"border-radius: 2px; text-indent: 20px; width: auto; padding: 0px 4px 0px 0px; text-align: center; font: bold 11px\/20px 'Helvetica Neue',Helvetica,sans-serif; color: #ffffff; background: #bd081c  no-repeat scroll 3px 50% \/ 14px 14px; position: absolute; opacity: 1; z-index: 8675309; display: none; cursor: pointer;\">Save<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"mh-excerpt\"><p>Stripe is one of the most widely used payment gateways currently. It is also one of the best for developers because it allows very easy <a class=\"mh-excerpt-more\" href=\"https:\/\/truelogic.org\/wordpress\/2016\/06\/07\/accepting-stripe-payments-in-android2\/\" title=\"Accepting Stripe Payments in Android\">[&#8230;]<\/a><\/p>\n<\/div>","protected":false},"author":1,"featured_media":2681,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[295],"tags":[],"class_list":["post-2666","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-android-dev"],"_links":{"self":[{"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/posts\/2666","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/comments?post=2666"}],"version-history":[{"count":10,"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/posts\/2666\/revisions"}],"predecessor-version":[{"id":2680,"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/posts\/2666\/revisions\/2680"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/media\/2681"}],"wp:attachment":[{"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/media?parent=2666"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/categories?post=2666"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/tags?post=2666"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}