/** * Invoice the customer for the given amount.nfig * * @param string $description * @param int $amount * @param array $options * @return bool * * @throws \Stripe\Error\Card */ public function invoiceFor($description, $amount, array $options = []) { if (!$this->stripe_id) { throw new InvalidArgumentException('User is not a customer. See the createAsStripeCustomer method.'); } $options = array_merge(['customer' => $this->stripe_id, 'amount' => $amount, 'currency' => $this->preferredCurrency(), 'description' => $description], $options); StripeInvoiceItem::create($options, ['api_key' => $this->getStripeKey()]); return $this->invoice(); }
public function testUpcoming() { authorizeFromEnv(); $customer = self::createTestCustomer(); InvoiceItem::create(array('customer' => $customer->id, 'amount' => 0, 'currency' => 'usd')); $invoice = Invoice::upcoming(array('customer' => $customer->id)); $this->assertEqual($invoice->customer, $customer->id); $this->assertEqual($invoice->attempted, false); }
/** * Process registration * * @since 2.1 */ public function process_signup() { \Stripe\Stripe::setApiKey($this->secret_key); $paid = false; $member = new RCP_Member($this->user_id); $customer_exists = false; if (empty($_POST['stripeToken'])) { wp_die(__('Missing Stripe token, please try again or contact support if the issue persists.', 'rcp'), __('Error', 'rcp'), array('response' => 400)); } $customer_id = $member->get_payment_profile_id(); if ($customer_id) { $customer_exists = true; try { // Update the customer to ensure their card data is up to date $customer = \Stripe\Customer::retrieve($customer_id); if (isset($customer->deleted) && $customer->deleted) { // This customer was deleted $customer_exists = false; } // No customer found } catch (Exception $e) { $customer_exists = false; } } if (empty($customer_exists)) { try { $customer_args = array('card' => $_POST['stripeToken'], 'email' => $this->email); $customer = \Stripe\Customer::create(apply_filters('rcp_stripe_customer_create_args', $customer_args, $this)); // A temporary invoice is created to force the customer's currency to be set to the store currency. See https://github.com/restrictcontentpro/restrict-content-pro/issues/549 if (!empty($this->signup_fee)) { \Stripe\InvoiceItem::create(array('customer' => $customer->id, 'amount' => 0, 'currency' => rcp_get_currency(), 'description' => 'Setting Customer Currency')); $temp_invoice = \Stripe\Invoice::create(array('customer' => $customer->id)); } $member->set_payment_profile_id($customer->id); } catch (Exception $e) { $this->handle_processing_error($e); } } else { $customer->source = $_POST['stripeToken']; } $customer->description = 'User ID: ' . $this->user_id . ' - User Email: ' . $this->email . ' Subscription: ' . $this->subscription_name; $customer->metadata = array('user_id' => $this->user_id, 'email' => $this->email, 'subscription' => $this->subscription_name); $customer->save(); if ($this->auto_renew) { // process a subscription sign up if (!($plan_id = $this->plan_exists($this->subscription_name))) { // create the plan if it doesn't exist $plan_id = $this->create_plan($this->subscription_name); } try { // Add fees before the plan is updated and charged if (!empty($this->signup_fee)) { $customer->account_balance = $customer->account_balance + $this->signup_fee * rcp_stripe_get_currency_multiplier(); // Add additional amount to initial payment (in cents) $customer->save(); if (isset($temp_invoice)) { $invoice = \Stripe\Invoice::retrieve($temp_invoice->id); $invoice->closed = true; $invoice->save(); unset($temp_invoice, $invoice); } } // clean up any past due or unpaid subscriptions before upgrading/downgrading foreach ($customer->subscriptions->all()->data as $subscription) { // check if we are renewing an existing subscription. This should not ever be 'active', if it is Stripe // will do nothing. If it is 'past_due' the most recent invoice will be paid and the subscription will become active if ($subscription->plan->id == $plan_id && in_array($subscription->status, array('active', 'past_due'))) { continue; } // remove any subscriptions that are past_due or inactive if (in_array($subscription->status, array('past_due', 'unpaid'))) { $subscription->cancel(); } } // If the customer has an existing subscription, we need to cancel it if ($member->just_upgraded() && rcp_can_member_cancel($member->ID)) { $cancelled = rcp_cancel_member_payment_profile($member->ID, false); } $sub_args = array('plan' => $plan_id, 'prorate' => false); if (!empty($this->discount_code)) { $sub_args['coupon'] = $this->discount_code; } // Set the customer's subscription in Stripe $subscription = $customer->subscriptions->create(array($sub_args)); $member->set_merchant_subscription_id($subscription->id); // subscription payments are recorded via webhook $paid = true; } catch (\Stripe\Error\Card $e) { $this->handle_processing_error($e); } catch (\Stripe\Error\InvalidRequest $e) { // Invalid parameters were supplied to Stripe's API $this->handle_processing_error($e); } catch (\Stripe\Error\Authentication $e) { // Authentication with Stripe's API failed // (maybe you changed API keys recently) $this->handle_processing_error($e); } catch (\Stripe\Error\ApiConnection $e) { // Network communication with Stripe failed $this->handle_processing_error($e); } catch (\Stripe\Error\Base $e) { // Display a very generic error to the user $this->handle_processing_error($e); } catch (Exception $e) { // Something else happened, completely unrelated to Stripe $error = '<p>' . __('An unidentified error occurred.', 'rcp') . '</p>'; $error .= print_r($e, true); wp_die($error, __('Error', 'rcp'), array('response' => 401)); } } else { // process a one time payment signup try { $charge = \Stripe\Charge::create(apply_filters('rcp_stripe_charge_create_args', array('amount' => round(($this->amount + $this->signup_fee) * rcp_stripe_get_currency_multiplier(), 0), 'currency' => strtolower($this->currency), 'customer' => $customer->id, 'description' => 'User ID: ' . $this->user_id . ' - User Email: ' . $this->email . ' Subscription: ' . $this->subscription_name, 'receipt_email' => $this->email, 'metadata' => array('email' => $this->email, 'user_id' => $this->user_id, 'level_id' => $this->subscription_id, 'level' => $this->subscription_name, 'key' => $this->subscription_key)), $this)); $payment_data = array('date' => date('Y-m-d H:i:s', current_time('timestamp')), 'subscription' => $this->subscription_name, 'payment_type' => 'Credit Card One Time', 'subscription_key' => $this->subscription_key, 'amount' => $this->amount + $this->signup_fee, 'user_id' => $this->user_id, 'transaction_id' => $charge->id); $rcp_payments = new RCP_Payments(); $rcp_payments->insert($payment_data); $paid = true; } catch (\Stripe\Error\Card $e) { $this->handle_processing_error($e); } catch (\Stripe\Error\InvalidRequest $e) { // Invalid parameters were supplied to Stripe's API $this->handle_processing_error($e); } catch (\Stripe\Error\Authentication $e) { // Authentication with Stripe's API failed // (maybe you changed API keys recently) $this->handle_processing_error($e); } catch (\Stripe\Error\ApiConnection $e) { // Network communication with Stripe failed $this->handle_processing_error($e); } catch (\Stripe\Error\Base $e) { // Display a very generic error to the user $this->handle_processing_error($e); } catch (Exception $e) { // Something else happened, completely unrelated to Stripe $error = '<p>' . __('An unidentified error occurred.', 'rcp') . '</p>'; $error .= print_r($e, true); wp_die($error, __('Error', 'rcp'), array('response' => 401)); } } if ($paid) { // If this is a one-time signup and the customer has an existing subscription, we need to cancel it if (!$this->auto_renew && $member->just_upgraded() && rcp_can_member_cancel($member->ID)) { $cancelled = rcp_cancel_member_payment_profile($member->ID, false); } // set this user to active $member->set_status('active'); $member->set_recurring($this->auto_renew); if (!is_user_logged_in()) { // log the new user in rcp_login_user_in($this->user_id, $this->user_name, $_POST['rcp_user_pass']); } if (!$this->auto_renew) { $member->set_expiration_date($member->calculate_expiration()); } do_action('rcp_stripe_signup', $this->user_id, $this); } else { wp_die(__('An error occurred, please contact the site administrator: ', 'rcp') . get_bloginfo('admin_email'), __('Error', 'rcp'), array('response' => 401)); } // redirect to the success page, or error page if something went wrong wp_redirect($this->return_url); exit; }
/** * Process registration * * @since 2.1 */ public function process_signup() { \Stripe\Stripe::setApiKey($this->secret_key); $paid = false; $member = new RCP_Member($this->user_id); $customer_exists = false; if (empty($_POST['stripeToken'])) { wp_die(__('Missing Stripe token, please try again or contact support if the issue persists.', 'rcp'), __('Error', 'rcp'), array('response' => 400)); } if ($this->auto_renew) { // process a subscription sign up $plan_id = strtolower(str_replace(' ', '', $this->subscription_name)); if (!$this->plan_exists($plan_id)) { // create the plan if it doesn't exist $this->create_plan($this->subscription_name); } try { $customer_id = $member->get_payment_profile_id(); if ($customer_id) { $customer_exists = true; try { // Update the customer to ensure their card data is up to date $customer = \Stripe\Customer::retrieve($customer_id); if (isset($customer->deleted) && $customer->deleted) { // This customer was deleted $customer_exists = false; } // No customer found } catch (Exception $e) { $customer_exists = false; } } if (!$customer_exists) { $customer_args = array('card' => $_POST['stripeToken'], 'email' => $this->email, 'description' => 'User ID: ' . $this->user_id . ' - User Email: ' . $this->email . ' Subscription: ' . $this->subscription_name); if (!empty($this->discount_code)) { $customer_args['coupon'] = $this->discount_code; } $customer = \Stripe\Customer::create(apply_filters('rcp_stripe_customer_create_args', $customer_args, $this)); } else { $customer->card = $_POST['stripeToken']; } // Add fees before the plan is updated and charged if (!empty($this->signup_fee)) { if ($this->signup_fee > 0) { $description = sprintf(__('Signup Fee for %s', 'rcp'), $this->subscription_name); } else { $description = sprintf(__('Signup Discount for %s', 'rcp'), $this->subscription_name); } \Stripe\InvoiceItem::create(apply_filters('rcp_stripe_invoice_item_create_args', array('customer' => $customer->id, 'amount' => $this->signup_fee * 100, 'currency' => strtolower($this->currency), 'description' => $description), $this, $customer)); // Create the invoice containing taxes / discounts / fees $invoice = \Stripe\Invoice::create(apply_filters('rcp_stripe_invoice_create_args', array('customer' => $customer->id), $this, $customer)); } if (!empty($this->discount_code)) { $customer->coupon = $this->discount_code; } // Save the card and any coupon $customer->save(); // Process the invoice if there is one if (!empty($invoice)) { $invoice->pay(); } // Update the customer's subscription in Stripe $customer->updateSubscription(array('plan' => $plan_id)); $member->set_payment_profile_id($customer->id); // subscription payments are recorded via webhook $paid = true; } catch (\Stripe\Error\Card $e) { $body = $e->getJsonBody(); $err = $body['error']; $error = '<h4>' . __('An error occurred', 'rcp') . '</h4>'; if (isset($err['code'])) { $error .= '<p>' . sprintf(__('Error code: %s', 'rcp'), $err['code']) . '</p>'; } $error .= "<p>Status: " . $e->getHttpStatus() . "</p>"; $error .= "<p>Message: " . $err['message'] . "</p>"; wp_die($error, __('Error', 'rcp'), array('response' => '401')); exit; } catch (\Stripe\Error\InvalidRequest $e) { // Invalid parameters were supplied to Stripe's API $body = $e->getJsonBody(); $err = $body['error']; $error = '<h4>' . __('An error occurred', 'rcp') . '</h4>'; if (isset($err['code'])) { $error .= '<p>' . sprintf(__('Error code: %s', 'rcp'), $err['code']) . '</p>'; } $error .= "<p>Status: " . $e->getHttpStatus() . "</p>"; $error .= "<p>Message: " . $err['message'] . "</p>"; wp_die($error, __('Error', 'rcp'), array('response' => '401')); } catch (\Stripe\Error\Authentication $e) { // Authentication with Stripe's API failed // (maybe you changed API keys recently) $body = $e->getJsonBody(); $err = $body['error']; $error = '<h4>' . __('An error occurred', 'rcp') . '</h4>'; if (isset($err['code'])) { $error .= '<p>' . sprintf(__('Error code: %s', 'rcp'), $err['code']) . '</p>'; } $error .= "<p>Status: " . $e->getHttpStatus() . "</p>"; $error .= "<p>Message: " . $err['message'] . "</p>"; wp_die($error, __('Error', 'rcp'), array('response' => '401')); } catch (\Stripe\Error\ApiConnection $e) { // Network communication with Stripe failed $body = $e->getJsonBody(); $err = $body['error']; $error = '<h4>' . __('An error occurred', 'rcp') . '</h4>'; if (isset($err['code'])) { $error .= '<p>' . sprintf(__('Error code: %s', 'rcp'), $err['code']) . '</p>'; } $error .= "<p>Status: " . $e->getHttpStatus() . "</p>"; $error .= "<p>Message: " . $err['message'] . "</p>"; wp_die($error, __('Error', 'rcp'), array('response' => '401')); } catch (\Stripe\Error\Base $e) { // Display a very generic error to the user $body = $e->getJsonBody(); $err = $body['error']; $error = '<h4>' . __('An error occurred', 'rcp') . '</h4>'; if (isset($err['code'])) { $error .= '<p>' . sprintf(__('Error code: %s', 'rcp'), $err['code']) . '</p>'; } $error .= "<p>Status: " . $e->getHttpStatus() . "</p>"; $error .= "<p>Message: " . $err['message'] . "</p>"; wp_die($error, __('Error', 'rcp'), array('response' => '401')); } catch (Exception $e) { // Something else happened, completely unrelated to Stripe $error = '<p>' . __('An unidentified error occurred.', 'rcp') . '</p>'; $error .= print_r($e, true); wp_die($error, __('Error', 'rcp'), array('response' => '401')); } } else { // process a one time payment signup try { $charge = \Stripe\Charge::create(apply_filters('rcp_stripe_charge_create_args', array('amount' => $this->amount * 100, 'currency' => strtolower($this->currency), 'card' => $_POST['stripeToken'], 'description' => 'User ID: ' . $this->user_id . ' - User Email: ' . $this->email . ' Subscription: ' . $this->subscription_name, 'receipt_email' => $this->email, 'metadata' => array('email' => $this->email, 'user_id' => $this->user_id, 'level_id' => $this->subscription_id, 'level' => $this->subscription_name, 'key' => $this->subscription_key)), $this)); $payment_data = array('date' => date('Y-m-d g:i:s', current_time('timestamp')), 'subscription' => $this->subscription_name, 'payment_type' => 'Credit Card One Time', 'subscription_key' => $this->subscription_key, 'amount' => $this->amount, 'user_id' => $this->user_id, 'transaction_id' => $charge->id); $rcp_payments = new RCP_Payments(); $rcp_payments->insert($payment_data); $paid = true; } catch (\Stripe\Error\Card $e) { $body = $e->getJsonBody(); $err = $body['error']; $error = '<h4>' . __('An error occurred', 'rcp') . '</h4>'; if (isset($err['code'])) { $error .= '<p>' . sprintf(__('Error code: %s', 'rcp'), $err['code']) . '</p>'; } $error .= "<p>Status: " . $e->getHttpStatus() . "</p>"; $error .= "<p>Message: " . $err['message'] . "</p>"; wp_die($error, __('Error', 'rcp'), array('response' => '401')); exit; } catch (\Stripe\Error\InvalidRequest $e) { // Invalid parameters were supplied to Stripe's API $body = $e->getJsonBody(); $err = $body['error']; $error = '<h4>' . __('An error occurred', 'rcp') . '</h4>'; if (isset($err['code'])) { $error .= '<p>' . sprintf(__('Error code: %s', 'rcp'), $err['code']) . '</p>'; } $error .= "<p>Status: " . $e->getHttpStatus() . "</p>"; $error .= "<p>Message: " . $err['message'] . "</p>"; wp_die($error, __('Error', 'rcp'), array('response' => '401')); } catch (\Stripe\Error\Authentication $e) { // Authentication with Stripe's API failed // (maybe you changed API keys recently) $body = $e->getJsonBody(); $err = $body['error']; $error = '<h4>' . __('An error occurred', 'rcp') . '</h4>'; if (isset($err['code'])) { $error .= '<p>' . sprintf(__('Error code: %s', 'rcp'), $err['code']) . '</p>'; } $error .= "<p>Status: " . $e->getHttpStatus() . "</p>"; $error .= "<p>Message: " . $err['message'] . "</p>"; wp_die($error, __('Error', 'rcp'), array('response' => '401')); } catch (\Stripe\Error\ApiConnection $e) { // Network communication with Stripe failed $body = $e->getJsonBody(); $err = $body['error']; $error = '<h4>' . __('An error occurred', 'rcp') . '</h4>'; if (isset($err['code'])) { $error .= '<p>' . sprintf(__('Error code: %s', 'rcp'), $err['code']) . '</p>'; } $error .= "<p>Status: " . $e->getHttpStatus() . "</p>"; $error .= "<p>Message: " . $err['message'] . "</p>"; wp_die($error, __('Error', 'rcp'), array('response' => '401')); } catch (\Stripe\Error\Base $e) { // Display a very generic error to the user $body = $e->getJsonBody(); $err = $body['error']; $error = '<h4>' . __('An error occurred', 'rcp') . '</h4>'; if (isset($err['code'])) { $error .= '<p>' . sprintf(__('Error code: %s', 'rcp'), $err['code']) . '</p>'; } $error .= "<p>Status: " . $e->getHttpStatus() . "</p>"; $error .= "<p>Message: " . $err['message'] . "</p>"; wp_die($error, __('Error', 'rcp'), array('response' => '401')); } catch (Exception $e) { // Something else happened, completely unrelated to Stripe $error = '<p>' . __('An unidentified error occurred.', 'rcp') . '</p>'; $error .= print_r($e, true); wp_die($error, __('Error', 'rcp'), array('response' => '401')); } } if ($paid) { // set this user to active $member->set_status('active'); $member->set_recurring($this->auto_renew); if (!is_user_logged_in()) { // log the new user in rcp_login_user_in($this->user_id, $this->user_name, $_POST['rcp_user_pass']); } do_action('rcp_stripe_signup', $this->user_id, $this); } else { wp_die(__('An error occurred, please contact the site administrator: ', 'rcp') . get_bloginfo('admin_email'), __('Error', 'rcp'), array('response' => '401')); } // redirect to the success page, or error page if something went wrong wp_redirect($this->return_url); exit; }