churnbuster.rb

 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
29protected
30
31	def format_tx(customer, amount, txid)
32		{
33			source: "braintree",
34			source_id: txid,
35			amount_in_cents: (amount * 100).to_i,
36			currency: customer.currency
37		}
38	end
39
40	def format_customer(customer)
41		unprox = ProxiedJID.new(customer.jid).unproxied.to_s
42		email = "#{unprox.gsub(/@/, '=40').gsub(/\./, '=2e')}@smtp.cheogram.com"
43		{
44			source: "braintree",
45			source_id: customer.customer_id,
46			email: email,
47			properties: {}
48		}
49	end
50
51	def post_json(url, data)
52		EM::HttpRequest.new(
53			url,
54			tls: { verify_peer: true }
55		).apost(
56			head: {
57				"Authorization" => [@account_id, @api_key],
58				"Content-Type" => "application/json"
59			},
60			body: data.to_json
61		)
62	end
63end