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