1# frozen_string_literal: true
2
3require "bigdecimal"
4require "em-http"
5require "em_promise"
6require "em-synchrony/em-http" # For apost vs post
7require "json"
8require "securerandom"
9
10class Churnbuster
11 def initialize(
12 account_id: CONFIG.dig(:churnbuster, :account_id),
13 api_key: CONFIG.dig(:churnbuster, :api_key)
14 )
15 @account_id = account_id
16 @api_key = api_key
17 end
18
19 def failed_payment(customer, amount, txid)
20 post_json(
21 "https://api.churnbuster.io/v1/failed_payments",
22 {
23 customer: format_customer(customer),
24 payment: format_tx(customer, amount, txid)
25 }
26 )
27 end
28
29 def successful_payment(customer, amount, txid)
30 post_json(
31 "https://api.churnbuster.io/v1/successful_payments",
32 {
33 customer: format_customer(customer),
34 payment: format_tx(customer, amount, txid)
35 }
36 )
37 end
38
39 def cancellation(customer)
40 post_json(
41 "https://api.churnbuster.io/v1/cancellations",
42 {
43 customer: format_customer(customer),
44 subscription: {
45 source: "braintree",
46 source_id: customer.customer_id
47 }
48 }
49 )
50 end
51
52protected
53
54 def format_tx(customer, amount, txid)
55 {
56 source: "braintree",
57 source_id: txid,
58 amount_in_cents: (amount * 100).to_i,
59 currency: customer.currency
60 }
61 end
62
63 def format_customer(customer)
64 unprox = ProxiedJID.new(customer.jid).unproxied.to_s
65 email = "#{unprox.gsub(/@/, '=40').gsub(/\./, '=2e')}@smtp.cheogram.com"
66 {
67 source: "braintree",
68 source_id: customer.customer_id,
69 email: email,
70 properties: {}
71 }
72 end
73
74 def post_json(url, data)
75 EM::HttpRequest.new(
76 url,
77 tls: { verify_peer: true }
78 ).apost(
79 head: {
80 "Authorization" => [@account_id, @api_key],
81 "Content-Type" => "application/json"
82 },
83 body: data.to_json
84 )
85 end
86end