MS_Gateway_Stripe_Api

Stripe Gateway API Integration.

Defined (1)

The class is defined in the following location(s).

/app/gateway/stripe/class-ms-gateway-stripe-api.php  
  1. class MS_Gateway_Stripe_Api extends MS_Model_Option { 
  2.  
  3. const ID = 'stripe'; 
  4.  
  5. /** 
  6. * Gateway singleton instance. 
  7. * @since 1.0.0 
  8. * @var string $instance 
  9. */ 
  10. public static $instance; 
  11.  
  12. /** 
  13. * Holds a reference to the parent gateway (either stripe or stripeplan) 
  14. * @since 1.0.1.0 
  15. * @var MS_Gateway_Stripe|MS_Gateway_Stripeplan 
  16. */ 
  17. protected $_gateway = null; 
  18.  
  19. /** 
  20. * Sets the parent gateway of the API object. 
  21. * The parent gateway object is used to fetch the API keys. 
  22. * @since 1.0.1.0 
  23. * @param MS_Gateway $gateway The parent gateway. 
  24. */ 
  25. public function set_gateway( $gateway ) { 
  26. static $Stripe_Loaded = false; 
  27.  
  28. if ( ! $Stripe_Loaded ) { 
  29. require_once MS_Plugin::instance()->dir . '/lib/stripe-php/lib/Stripe.php'; 
  30.  
  31. do_action( 
  32. 'ms_gateway_stripe_load_stripe_lib_after',  
  33. $this 
  34. ); 
  35.  
  36. $Stripe_Loaded = true; 
  37.  
  38. $this->_gateway = $gateway; 
  39.  
  40. $secret_key = $this->_gateway->get_secret_key(); 
  41. M2_Stripe::setApiKey( $secret_key ); 
  42.  
  43. /** 
  44. * Get Member's Stripe Customer Object, creates a new customer if not found. 
  45. * @since 1.0.0 
  46. * @internal 
  47. * @param MS_Model_Member $member The member. 
  48. * @param string $token The credit card token. 
  49. */ 
  50. public function get_stripe_customer( $member, $token ) { 
  51. $customer = $this->find_customer( $member ); 
  52.  
  53. if ( empty( $customer ) ) { 
  54. $customer = M2_Stripe_Customer::create( 
  55. array( 
  56. 'card' => $token,  
  57. 'email' => $member->email,  
  58. ); 
  59. $member->set_gateway_profile( self::ID, 'customer_id', $customer->id ); 
  60. $member->save(); 
  61. } else { 
  62. $this->add_card( $member, $customer, $token ); 
  63.  
  64. return apply_filters( 
  65. 'ms_gateway_stripe_get_stripe_customer',  
  66. $customer,  
  67. $member,  
  68. $this 
  69. ); 
  70.  
  71. /** 
  72. * Get Member's Stripe Customer Object. 
  73. * @since 1.0.0 
  74. * @internal 
  75. * @param MS_Model_Member $member The member. 
  76. */ 
  77. public function find_customer( $member ) { 
  78. $customer_id = $member->get_gateway_profile( self::ID, 'customer_id' ); 
  79. $customer = null; 
  80.  
  81. if ( ! empty( $customer_id ) ) { 
  82. $customer = M2_Stripe_Customer::retrieve( $customer_id ); 
  83.  
  84. // Seems like the customer was manually deleted on Stripe website. 
  85. if ( isset( $customer->deleted ) && $customer->deleted ) { 
  86. $customer = null; 
  87. $member->set_gateway_profile( self::ID, 'customer_id', '' ); 
  88.  
  89. return apply_filters( 
  90. 'ms_gateway_stripe_find_customer',  
  91. $customer,  
  92. $member,  
  93. $this 
  94. ); 
  95.  
  96. /** 
  97. * Add card info to Stripe customer profile and to WordPress user meta. 
  98. * @since 1.0.0 
  99. * @api 
  100. * @param MS_Model_Member $member The member model. 
  101. * @param M2_Stripe_Customer $customer The stripe customer object. 
  102. * @param string $token The stripe card token generated by the gateway. 
  103. */ 
  104. public function add_card( $member, $customer, $token ) { 
  105. $card = false; 
  106.  
  107. // 1. Save card to Stripe profile. 
  108.  
  109. // Stripe API until version 2015-02-16 
  110. if ( ! empty( $customer->cards ) ) { 
  111. $card = $customer->cards->create( array( 'card' => $token ) ); 
  112. $customer->default_card = $card->id; 
  113.  
  114. // Stripe API since 2015-02-18 
  115. if ( ! empty( $customer->sources ) ) { 
  116. $card = $customer->sources->create( array( 'card' => $token ) ); 
  117. $customer->default_source = $card->id; 
  118.  
  119. if ( $card ) { 
  120. $customer->save(); 
  121.  
  122. /** 
  123. * This action is used by the Taxamo Add-on to check additional country 
  124. * evidence (CC country). 
  125. * @since 1.0.0 
  126. */ 
  127. do_action( 'ms_gateway_stripe_credit_card_saved', $card, $member, $this ); 
  128.  
  129. // 2. Save card to WordPress user meta. 
  130.  
  131. if ( $card ) { 
  132. $member->set_gateway_profile( 
  133. self::ID,  
  134. 'card_exp',  
  135. gmdate( 'Y-m-d', strtotime( "{$card->exp_year}-{$card->exp_month}-01" ) ) 
  136. ); 
  137. $member->set_gateway_profile( self::ID, 'card_num', $card->last4 ); 
  138. $member->save(); 
  139.  
  140. do_action( 
  141. 'ms_gateway_stripe_add_card_info_after',  
  142. $customer,  
  143. $token,  
  144. $this 
  145. ); 
  146.  
  147. /** 
  148. * Creates a one-time charge that is immediately captured. 
  149. * This means the money is instantly transferred to our own stripe account. 
  150. * @since 1.0.0 
  151. * @internal 
  152. * @param M2_Stripe_Customer $customer Stripe customer to charge. 
  153. * @param float $amount Amount in currency (i.e. in USD, not in cents) 
  154. * @param string $currency 3-digit currency code. 
  155. * @param string $description This is displayed on the invoice to customer. 
  156. * @return M2_Stripe_Charge The resulting charge object. 
  157. */ 
  158. public function charge( $customer, $amount, $currency, $description ) { 
  159. $charge = M2_Stripe_Charge::create( 
  160. array( 
  161. 'customer' => $customer->id,  
  162. 'amount' => intval( $amount * 100 ), // Amount in cents! 
  163. 'currency' => strtolower( $currency ),  
  164. 'description' => $description,  
  165. ); 
  166.  
  167. return apply_filters( 
  168. 'ms_gateway_stripe_charge',  
  169. $charge,  
  170. $customer,  
  171. $amount,  
  172. $currency,  
  173. $description,  
  174. $this 
  175. ); 
  176.  
  177. /** 
  178. * Fetches an existing subscription from Stripe and returns it. 
  179. * If the specified customer did not subscribe to the membership then 
  180. * boolean FALSE will be returned. 
  181. * @since 1.0.0 
  182. * @internal 
  183. * @param M2_Stripe_Customer $customer Stripe customer to charge. 
  184. * @param MS_Model_Membership $membership The membership. 
  185. * @return M2_Stripe_Subscription|false The resulting charge object. 
  186. */ 
  187. public function get_subscription( $customer, $membership ) { 
  188. $plan_id = MS_Gateway_Stripeplan::get_the_id( 
  189. $membership->id,  
  190. 'plan' 
  191. ); 
  192.  
  193. /** 
  194. * Check all subscriptions of the customer and find the subscription 
  195. * for the specified membership. 
  196. */ 
  197. $last_checked = false; 
  198. $has_more = false; 
  199. $subscription = false; 
  200.  
  201. do { 
  202. $args = array(); 
  203. if ( $last_checked ) { 
  204. $args['starting_after'] = $last_checked; 
  205. $active_subs = $customer->subscriptions->all( $args ); 
  206. $has_more = $active_subs->has_more; 
  207.  
  208. foreach ( $active_subs->data as $sub ) { 
  209. if ( $sub->plan->id == $plan_id ) { 
  210. $subscription = $sub; 
  211. $has_more = false; 
  212. break 2; 
  213. $last_checked = $sub->id; 
  214. } while ( $has_more ); 
  215.  
  216. return apply_filters( 
  217. 'ms_gateway_stripe_get_subscription',  
  218. $subscription,  
  219. $customer,  
  220. $membership,  
  221. $this 
  222. ); 
  223.  
  224. /** 
  225. * Creates a subscription that starts immediately. 
  226. * @since 1.0.0 
  227. * @internal 
  228. * @param M2_Stripe_Customer $customer Stripe customer to charge. 
  229. * @param MS_Model_Invoice $invoice The relevant invoice. 
  230. * @return M2_Stripe_Subscription The resulting charge object. 
  231. */ 
  232. public function subscribe( $customer, $invoice ) { 
  233. $membership = $invoice->get_membership(); 
  234. $plan_id = MS_Gateway_Stripeplan::get_the_id( 
  235. $membership->id,  
  236. 'plan' 
  237. ); 
  238.  
  239. $subscription = self::get_subscription( $customer, $membership ); 
  240.  
  241. /** 
  242. * If no active subscription was found for the membership create it. 
  243. */ 
  244. if ( ! $subscription ) { 
  245. $tax_percent = null; 
  246. $coupon_id = null; 
  247.  
  248. if ( is_numeric( $invoice->tax_rate ) && $invoice->tax_rate > 0 ) { 
  249. $tax_percent = floatval( $invoice->tax_rate ); 
  250. if ( $invoice->coupon_id ) { 
  251. $coupon_id = MS_Gateway_Stripeplan::get_the_id( 
  252. $invoice->coupon_id,  
  253. 'coupon' 
  254. ); 
  255.  
  256. $args = array( 
  257. 'plan' => $plan_id,  
  258. 'tax_percent' => $tax_percent,  
  259. 'coupon' => $coupon_id,  
  260. ); 
  261. $subscription = $customer->subscriptions->create( $args ); 
  262.  
  263. return apply_filters( 
  264. 'ms_gateway_stripe_subscribe',  
  265. $subscription,  
  266. $customer,  
  267. $invoice,  
  268. $membership,  
  269. $this 
  270. ); 
  271.  
  272. /** 
  273. * Creates or updates the payment plan specified by the function parameter. 
  274. * @since 1.0.0 
  275. * @internal 
  276. * @param array $plan_data The plan-object containing all details for Stripe. 
  277. */ 
  278. public function create_or_update_plan( $plan_data ) { 
  279. $item_id = $plan_data['id']; 
  280. $all_items = MS_Factory::get_transient( 'ms_stripeplan_plans' ); 
  281. $all_items = lib3()->array->get( $all_items ); 
  282.  
  283. if ( ! isset( $all_items[$item_id] ) 
  284. || ! is_a( $all_items[$item_id], 'M2_Stripe_Plan' ) 
  285. ) { 
  286. try { 
  287. $item = M2_Stripe_Plan::retrieve( $item_id ); 
  288. } catch( Exception $e ) { 
  289. // If the plan does not exist then stripe will throw an Exception. 
  290. $item = false; 
  291. $all_items[$item_id] = $item; 
  292. } else { 
  293. $item = $all_items[$item_id]; 
  294.  
  295. /** 
  296. * Stripe can only update the plan-name, so we have to delete and 
  297. * recreate the plan manually. 
  298. */ 
  299. if ( $item && is_a( $item, 'M2_Stripe_Plan' ) ) { 
  300. $item->delete(); 
  301. $all_items[$item_id] = false; 
  302.  
  303. if ( $plan_data['amount'] > 0 ) { 
  304. $item = M2_Stripe_Plan::create( $plan_data ); 
  305. $all_items[$item_id] = $item; 
  306.  
  307. MS_Factory::set_transient( 
  308. 'ms_stripeplan_plans',  
  309. $all_items,  
  310. HOUR_IN_SECONDS 
  311. ); 
  312.  
  313. /** 
  314. * Creates or updates the coupon specified by the function parameter. 
  315. * @since 1.0.0 
  316. * @internal 
  317. * @param array $coupon_data The object containing all details for Stripe. 
  318. */ 
  319. public function create_or_update_coupon( $coupon_data ) { 
  320. $item_id = $coupon_data['id']; 
  321. $all_items = MS_Factory::get_transient( 'ms_stripeplan_plans' ); 
  322. $all_items = lib3()->array->get( $all_items ); 
  323.  
  324. if ( ! isset( $all_items[$item_id] ) 
  325. || ! is_a( $all_items[$item_id], 'M2_Stripe_Coupon' ) 
  326. ) { 
  327. try { 
  328. $item = M2_Stripe_Coupon::retrieve( $item_id ); 
  329. } catch( Exception $e ) { 
  330. // If the coupon does not exist then stripe will throw an Exception. 
  331. $item = false; 
  332. $all_items[$item_id] = $item; 
  333. } else { 
  334. $item = $all_items[$item_id]; 
  335.  
  336. /** 
  337. * Stripe can only update the coupon-name, so we have to delete and 
  338. * recreate the coupon manually. 
  339. */ 
  340. if ( $item && is_a( $item, 'M2_Stripe_Coupon' ) ) { 
  341. $item->delete(); 
  342. $all_items[$item_id] = false; 
  343.  
  344. $item = M2_Stripe_Coupon::create( $coupon_data ); 
  345. $all_items[$item_id] = $item; 
  346.  
  347. MS_Factory::set_transient( 
  348. 'ms_stripeplan_coupons',  
  349. $all_items,  
  350. HOUR_IN_SECONDS 
  351. ); 
  352.  
  353. /** 
  354. * Little hack to force the plugin to store/load the stripe_api data in same 
  355. * option-field as the stripe-gateway settings. 
  356. * @since 1.0.0 
  357. * @return string 
  358. */ 
  359. public function option_key() { 
  360. // Option key should be all lowercase. 
  361. $key = 'ms_gateway_stripe'; 
  362.  
  363. // Network-wide IS PRO ONLY! 
  364.  
  365. return $key;