我很难从我的Android应用程序到我的服务器进行HTTP-POST,以便收取Stripe费用。
我跟踪tutorial found on the Stripe website后,我的Stripe服务器自行运行正常。我的工作申请can be found here。
就像洞察力一样,我的Charges控制器看起来像:
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
我正在尝试将令牌传递给我的服务器以便创建费用。但是,它会导致以下错误:
E/Volley: [714] BasicNetwork.performRequest: Unexpected response code 404 for https://agile-chamber-46872.herokuapp.com/charges/create?stripeToken=tok_*************&stripeEmail=xxxxxxxx@gmail.com
这是我的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代码才能在/create
正确地发布到我的服务器的REST API?
答案 0 :(得分:1)
一些事情:
首先,对于您的Android应用程序所针对的API端点,您需要禁用Rails表单的真实性检查。查看skip_before_action :verify_authenticity_token
Volley正在从你的Rails应用程序中获取HTTP 404,所以它与你的Android应用程序本身无关;您正在使用错误的URL /指向API端点的路径
默认情况下,Rails会在收到HTTP POST时自动调用控制器上的create
操作 - 因此,我猜你真的只想对
https://agile-chamber-46872.herokuapp.com/charges
Rails会将内部路由到create
操作 - 您不需要在Android HTTP请求中明确指定此内容。
我相信这是后一点,这是您的HTTP 404的真正来源
通过curl点击你的API:
$ curl -XPOST "https://agile-chamber-46872.herokuapp.com/charges?stripeToken=tok_abc&stripeEmail=foo@gmail.com"
HTTP 500中的结果 - 不是404,所以我们到了某个地方。检查您的Rail日志以查找错误来源。考虑启用日志收集Heroku附加组件,如Papertrail