创建从Android客户端到服务器的条纹收费
我很难从我的Android应用程序向服务器发送HTTP-POST,以便收取条带费用 我的条带服务器在我遵循。我的工作申请 作为一种见解,我的收费控制器看起来像:创建从Android客户端到服务器的条纹收费,android,ruby-on-rails,stripe-payments,Android,Ruby On Rails,Stripe Payments,我很难从我的Android应用程序向服务器发送HTTP-POST,以便收取条带费用 我的条带服务器在我遵循。我的工作申请 作为一种见解,我的收费控制器看起来像: class ChargesController < ApplicationController protect_from_forgery def new end def create # Amount in cents @amount = 500 custom
class ChargesController < ApplicationController
protect_from_forgery
def new
end
def create
# Amount in cents
@amount = 500
customer = Stripe::Customer.create(
:email => params[:stripeEmail],
:source => params[:stripeToken]
)
charge = Stripe::Charge.create(
:customer => customer.id,
:amount => @amount,
:description => 'Rails Stripe customer',
:currency => 'usd'
)
rescue Stripe::CardError => e
flash[:error] = e.message
redirect_to new_charge_path
end
end
这是我的android代码,我正在尝试向我的服务器发送HTTP POST:
package com.snapwebdevelopment.scanhappy
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.stripe.android.*;
import com.braintreepayments.cardform.view.CardForm;
import com.stripe.android.exception.AuthenticationException;
import com.stripe.android.model.Card;
import com.stripe.android.model.Token;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import com.android.volley.Response;
import static java.security.AccessController.getContext;
public class CreditCardActivity extends AppCompatActivity {
private CardForm cardForm;
private Button makePaymentButton;
private Stripe stripe;
private HashMap<String, Object> chargeInfo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_credit_card);
makePaymentButton = (Button) findViewById(R.id.makePaymentButton);
cardForm = (CardForm) findViewById(R.id.card_form);
cardForm.cardRequired(true)
.expirationRequired(true)
.cvvRequired(true)
.postalCodeRequired(true)
.mobileNumberRequired(true)
.mobileNumberExplanation("SMS is required on this number")
.actionLabel("Purchase")
.setup(this);
makePaymentButton.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
validateCard();
}
});
}
private void validateCard(){
chargeInfo = new HashMap<>();
Card card = new Card(
cardForm.getCardNumber(),
Integer.valueOf(cardForm.getExpirationMonth()),
Integer.valueOf(cardForm.getExpirationYear()),
cardForm.getCvv()
);
card.validateNumber();
card.validateCVC();
stripe = null;
try {
stripe = new Stripe("pk_test_*************");
stripe.createToken(
card,
new TokenCallback() {
public void onSuccess(Token token) {
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(CreditCardActivity.this);
String url = "https://agile-chamber-46872.herokuapp.com/charges/create?stripeToken=" + token.getId() + "&stripeEmail=rebeccasheeler@gmail.com";
// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
// your response
Log.d("HTTP-RESPONSE", response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// error
}
}){
@Override
public byte[] getBody() throws AuthFailureError {
String your_string_json = ""; // put your json
return your_string_json.getBytes();
}
};
// Add the request to the RequestQueue.
queue.add(stringRequest);
}
public void onError(Exception error) {
// Show localized error message
Toast.makeText(CreditCardActivity.this, error.getLocalizedMessage(), Toast.LENGTH_LONG).show();
}
}
);
} catch (AuthenticationException e) {
e.printStackTrace();
}
}
private void chargeUser() {
}
}
导入android.support.v7.app.app活动;
导入android.os.Bundle;
导入android.util.Log;
导入android.view.view;
导入android.widget.Button;
导入android.widget.Toast;
导入com.android.volley.AuthFailureError;
导入com.android.volley.Request;
导入com.android.volley.RequestQueue;
导入com.android.volley.VolleyError;
导入com.android.volley.toolbox.StringRequest;
导入com.android.volley.toolbox.volley;
导入com.stripe.android.*;
导入com.braintreepayments.cardform.view.cardform;
导入com.stripe.android.exception.AuthenticationException;
导入com.stripe.android.model.Card;
导入com.stripe.android.model.Token;
导入org.json.JSONException;
导入org.json.JSONObject;
导入java.io.IOException;
导入java.util.HashMap;
导入java.util.Map;
导入com.android.volley.Response;
导入静态java.security.AccessController.getContext;
公共类CreditCardActivity扩展了AppCompatActivity{
私人卡;
私有按钮makePaymentButton;
私人条纹;
私有HashMap chargeInfo;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity\u信用卡);
makePaymentButton=(按钮)findViewById(R.id.makePaymentButton);
cardForm=(cardForm)findviewbyd(R.id.card\u form);
cardForm.cardRequired(真)
.expirationRequired(true)
.cvvRequired(真)
.postalCodeRequired(正确)
.mobileNumberRequired(真)
.mobileNumberExplanation(“此号码需要短信”)
.actionLabel(“购买”)
.设置(本);
makePaymentButton.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
validateCard();
}
});
}
私有void validateCard(){
chargeInfo=newhashmap();
卡=新卡(
cardForm.getCardNumber(),
Integer.valueOf(cardForm.getExpirationMonth()),
Integer.valueOf(cardForm.getExpirationYear()),
cardForm.getCvv()
);
validateEnumber();
validateCVC();
stripe=null;
试一试{
条带=新条带(“pk_测试条带”);
stripe.createToken(
卡片
新令牌回调(){
成功时公共无效(令牌){
//实例化RequestQueue。
RequestQueue=Volley.newRequestQueue(CreditCardActivity.this);
字符串url=”https://agile-chamber-46872.herokuapp.com/charges/create?stripeToken=“+token.getId()+”&条带邮件=rebeccasheeler@gmail.com";
//从提供的URL请求字符串响应。
StringRequest StringRequest=新的StringRequest(Request.Method.POST,url,
新的Response.Listener(){
@凌驾
公共void onResponse(字符串响应){
//你的回答
Log.d(“HTTP响应”,响应);
}
},new Response.ErrorListener(){
@凌驾
公共无效onErrorResponse(截击错误){
//错误
}
}){
@凌驾
公共字节[]getBody()抛出AuthFailureError{
String您的_String_json=“”;//放入您的json
返回您的_字符串_json.getBytes();
}
};
//将请求添加到RequestQueue。
添加(stringRequest);
}
公共无效onError(异常错误){
//显示本地化错误消息
Toast.makeText(CreditCardActivity.this,error.getLocalizedMessage(),Toast.LENGTH_LONG.show();
}
}
);
}捕获(身份验证异常e){
e、 printStackTrace();
}
}
私有用户(){
}
}
我知道我在什么地方搞砸了。为了正确发布到服务器的REST api(位于/create
),我需要在Android代码中更改哪些内容?两件事:
- 首先,对于Android应用程序正在访问的API端点,您需要禁用Rails表单真实性检查。在操作之前查看
skip\u:验证\u真实性\u令牌
- Volley从你的Rails应用程序中获得了HTTP 404,因此它实际上与你的Android应用程序本身无关;您的API端点的URL/路径错误
- 默认情况下,Rails在收到HTTP POST时会自动调用控制器上的
操作——因此,我猜您真的只是想对其执行HTTP POSTcreate
ht
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.stripe.android.*;
import com.braintreepayments.cardform.view.CardForm;
import com.stripe.android.exception.AuthenticationException;
import com.stripe.android.model.Card;
import com.stripe.android.model.Token;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import com.android.volley.Response;
import static java.security.AccessController.getContext;
public class CreditCardActivity extends AppCompatActivity {
private CardForm cardForm;
private Button makePaymentButton;
private Stripe stripe;
private HashMap<String, Object> chargeInfo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_credit_card);
makePaymentButton = (Button) findViewById(R.id.makePaymentButton);
cardForm = (CardForm) findViewById(R.id.card_form);
cardForm.cardRequired(true)
.expirationRequired(true)
.cvvRequired(true)
.postalCodeRequired(true)
.mobileNumberRequired(true)
.mobileNumberExplanation("SMS is required on this number")
.actionLabel("Purchase")
.setup(this);
makePaymentButton.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
validateCard();
}
});
}
private void validateCard(){
chargeInfo = new HashMap<>();
Card card = new Card(
cardForm.getCardNumber(),
Integer.valueOf(cardForm.getExpirationMonth()),
Integer.valueOf(cardForm.getExpirationYear()),
cardForm.getCvv()
);
card.validateNumber();
card.validateCVC();
stripe = null;
try {
stripe = new Stripe("pk_test_*************");
stripe.createToken(
card,
new TokenCallback() {
public void onSuccess(Token token) {
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(CreditCardActivity.this);
String url = "https://agile-chamber-46872.herokuapp.com/charges/create?stripeToken=" + token.getId() + "&stripeEmail=rebeccasheeler@gmail.com";
// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
// your response
Log.d("HTTP-RESPONSE", response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// error
}
}){
@Override
public byte[] getBody() throws AuthFailureError {
String your_string_json = ""; // put your json
return your_string_json.getBytes();
}
};
// Add the request to the RequestQueue.
queue.add(stringRequest);
}
public void onError(Exception error) {
// Show localized error message
Toast.makeText(CreditCardActivity.this, error.getLocalizedMessage(), Toast.LENGTH_LONG).show();
}
}
);
} catch (AuthenticationException e) {
e.printStackTrace();
}
}
private void chargeUser() {
}
}
$ curl -XPOST "https://agile-chamber-46872.herokuapp.com/charges?stripeToken=tok_abc&stripeEmail=foo@gmail.com"