2012-03-09 14 views
19

So che esiste un'altra domanda simile a questa, ma non credo sia stata richiesta/risposta molto bene.Stripe Webhook on Rails

Fondamentalmente ho un'app funzionante per i binari in cui gli utenti possono iscriversi al mio abbonamento, inserire i dati della carta di credito, ecc. Tutto funziona. Ma ho bisogno di gestire la situazione in cui la carta di un utente viene rifiutata a un certo punto durante questo abbonamento ricorrente.

I tipi di eventi che inviano sono qui: https://stripe.com/docs/api?lang=ruby#event_types.

Ho problemi ad accedere all'oggetto charge.failed nella mia app.

I documenti sui webhook sono anche qui: https://stripe.com/docs/webhooks e qualsiasi aiuto sarebbe molto apprezzato.

+0

possibile duplicato di [Utilizzo di webhook Stripe con Rails] (http://stackoverflow.com/questions/9371566/using-stripe-webhooks-with-rails) – Hauleth

risposta

39

È necessario creare un controller per accettare e gestire sostanzialmente le richieste. È piuttosto semplice, sebbene non sia così semplice da avvolgere inizialmente la mente. Ecco un esempio del mio hooks_controller.rb:

class HooksController < ApplicationController 
    require 'json' 

    Stripe.api_key = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 

    def receiver 

    data_json = JSON.parse request.body.read 

    p data_json['data']['object']['customer'] 

    if data_json[:type] == "invoice.payment_succeeded" 
     make_active(data_event) 
    end 

    if data_json[:type] == "invoice.payment_failed" 
     make_inactive(data_event) 
    end 
    end 

    def make_active(data_event) 
    @profile = Profile.find(User.find_by_stripe_customer_token(data['data']['object']['customer']).profile) 
    if @profile.payment_received == false 
     @profile.payment_received = true 
     @profile.save! 
    end 
    end 

    def make_inactive(data_event) 
    @profile = Profile.find(User.find_by_stripe_customer_token(data['data']['object']['customer']).profile) 
    if @profile.payment_received == true 
     @profile.payment_received = false 
     @profile.save! 
    end 
    end 
end 

Il ricevitore def è la vista che si deve puntare il webhooks per sull'interfaccia stripe. La vista riceve il json e lo sto usando per aggiornare il profilo dell'utente nel caso in cui un pagamento fallisca o abbia esito positivo.

+0

Nice !! Penso che tu abbia ragione, inizialmente era un po 'intimidatorio, ma una volta capito che non era un grosso problema. Il mio controller in realtà sembrava un po 'come questo (anche se non così bello). Grazie! – Zach

+2

Molto utile! FYI il risultato dell'analisi JSON non è un hash indifferente, quindi potresti voler fare event_json = JSON :: parse (request.body.read) .with_indifferent_access. – runako

+10

Per la migliore pratica [di sicurezza], utilizzare l'id dell'evento ('data_json ['id']') per recuperare l'oggetto Stripe :: Event e quindi prelevare i dati da tale dato, poiché è sicuramente legit. - Come indicato nella [Pagina di riferimento di Stripe's webhooks] (https://stripe.com/docs/webhooks). – anxiety

0

Si tratta di una situazione tutt'altro che ideale test ...

banda ha bisogno di un modo per webhooks "forza" a scopo di test. Attualmente, l'abbonamento più breve che puoi fare è per 1 settimana (in modalità test); sarebbe molto più utile se fosse possibile impostarlo per 1 minuto, 1 ora, o anche semplicemente fare in modo che il callback si verifichi in tempo reale, in modo da poter testare il sistema di risposta API.

I test locali sono eccezionali, ma nulla sostituisce il mondo reale, dal vivo, tramite Internet, webhook/callback. Dover aspettare una settimana (!) Rallenta seriamente i progetti.

+0

Al giorno d'oggi, il minimo è 1 giorno ma sono ancora d'accordo con te. – Francisco