2017-01-31 6 views
0

У меня возникли трудности с выполнением HTTP-POST из моего приложения Android на мой сервер, чтобы сделать оплату за Stripe.Создание платы с Android-клиента на сервер для Stripe

Мой сервер Stripe работает отлично после того, как я последовал за tutorial found on the Stripe website. Мое рабочее приложение can be found here.

Подобно тому, как понимание, мой контроллер платы выглядит следующим образом:

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_*************&[email protected] 

Это мой андроид код, где я пытаюсь сделать HTTP POST, на мой сервер:

пакет 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() + "&[email protected]"; 

          // 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-коде, чтобы правильно отправить POST на REST api сервера на /create?

+0

@Selvin Исправьте меня, если я ошибаюсь, но 'getBody()' является методом из Volley.Request, предназначенным для анализа ответа с сервера. Я не думаю, что это объяснит ответ 404, который я получаю. Сейчас я просто хочу убедиться, что я правильно размещаю сервер, прежде чем разбирать ответ. – beckah

+0

Вы ошибаетесь, запрос не разобирается ... Он посылает, ну, тело .... – Selvin

+1

Волейбол говорит, что когда он пытается ударить по этому URL-адресу, он получает 404 - это то, что возвращается Rails.Таким образом, вы не должны попадать на правильный путь к конечной точке контроллера зарядки. –

ответ

1

Пара вещей:

  • Во-первых, для API конечных точек как это одно, что ваше Android приложение ударяя вам нужно будет отключить Rails формировать проверку подлинности. Посмотрите на skip_before_action :verify_authenticity_token

  • Volley получает HTTP 404 из вашего приложения Rails, поэтому он действительно не имеет ничего общего с вашим Android-приложением; вы попадаете в неправильный URL/Путь к своей конечной точке API

  • По умолчанию Rails автоматически вызывает действие create на контроллере, когда он получает HTTP POST - таким образом, я собираюсь угадать, что вы действительно просто хотите выполнить HTTP-POST против

https://agile-chamber-46872.herokuapp.com/charges

И Rails будет маршрут, который внутренне к create действия - вам не нужно явно указать это в запросе Android HTTP.

Я считаю, что это более поздний момент, который является истинным источником вашего HTTP 404

ударяя свой API с помощью завитка:

$ curl -XPOST "https://agile-chamber-46872.herokuapp.com/charges?stripeToken=tok_abc&[email protected]" 

результаты в HTTP 500 - который не является 404, поэтому мы «где-то. Проверьте источники ошибок для журнала ошибок. Подумайте о том, чтобы включить сбор журналов Heroku add-on, как Papertrail

+0

Это было именно оно! Я смог получить HTML-код для вида «Сборы» # create. Я буду продолжать забивать, чтобы посмотреть, могу ли я получить ответ, который я получаю от Stripe, но это было очень полезно. Спасибо! – beckah