Trouble downgrading/upgrading subscription on Stripe with PHP - php

I'm using Stripe for my recurring payment for my SAAS.
The problem I'm facing today is : I would like to offer to my client the choice to upgrade or downgrade their subscription to my service.
So the code I have actually is the following (according to the doc here):
\Stripe\Subscription::update($subscriptionID, [
'items' => [
'id' => $itemID,
'plan' => $planId
]
]);
The $subscriptionID, $itemID and $planId return my the right value I need but no update on the Stripe side.
I have just this error:
{
"error": {
"type": "invalid_request_error",
"message": "Invalid array",
"param": "items"
}
}
Any help on his please ?
Thanks.

You just need to cover items in one more array level, like so:
\Stripe\Subscription::update($subscriptionID, [
'items' => [
[
'id' => $itemID,
'plan' => $planId
]
]
]);

It was working using this code:
$customer = \Stripe\Customer::retrieve($CustomerId);
$subscription = $customer->subscriptions->retrieve($subscriptionID);
$customer->updateSubscription(['plan' => $planId]);
$customer->save();
Strange that the Stripe API do not talk about this solution.

Related

Stripe Bi-Weekly Subscription Description

Using Stripe's PHP API I was able to create a bi-weekly subscription for my customers but I'm having an issue, the "description" on all subscriptions is defaulting to "Subscription creation" and I can't seem to find a way to add a description although I thought the following code worked in the past (I updated the API since then). Please see my code below
case "BiWeekly":
try {
$product = \Stripe\Product::create([
"name" => "NEO Bi-Weekly Payments for $cname",
"type" => "service",
"statement_descriptor" => "NEO",
]);
$plan = \Stripe\Plan::create([
"product" => $product->id,
"amount" => $totalAmount,
"currency" => "usd",
"interval" => "week",
"interval_count" => 2,
"usage_type" => "licensed",
]);
$subscription = \Stripe\Subscription::create([
"customer" => $customer->id,
"items" => [["plan" => $plan->id]],
"metadata" => array("Name" => $cname, "For" => "NEO Bi-Wkly Pymts")
]);
} catch(\Stripe\Error\Card $e) {
$body = $e->getJsonBody();
$err = $body['error'];
header("Location: https://www.neo.com/declined/");
exit();
};
break;
Any help would be greatly appreciated!
As clarified in the comments - description='Subscription creation' is on the corresponding PaymentIntent (not the Subscription).
There's no easy way to do this - it's not possible to specify a description when creating the Subscription to automatically populate on the corresponding PaymentIntent.
What I suggest is to :
Create the Subscription with metadata
listen for the invoice.payment_succeeded webhook event - https://stripe.com/docs/webhooks
The invoice.payment_succeeded will contain the metadata from step 1 in lines and the payment_intent
Example
...
"lines": {
"object": "list",
"data": [
{
"id": "il_...",
"object": "line_item",
...
"metadata": {
"subscription_metadata": "some_value"
},
...
"payment_intent": "pi_...",
...
using the data from step 3, make a request to update the PaymentIntent's description
On a side note, you should no longer be creating Plans (which is deprecated), but should be creating Prices instead.

Bigcommerce cart 422: Missing required fields error

I'm using Laravel to consume the Bigcommerce V3 API.
I have ben able to succesfully create a new cart. But when trying to add an item to it, I keep getting a 422: Missing required fields error.
I'm making my request trough Guzzle like this:
return json_decode($this->client->getRestClient()
->post('carts/'.$cartId.'/items?include=line_items.physical_items.options', [
'Accept' => 'application/json',
'json' => [
'line_items' => [
'product_id' => 86,
'quantity' => 1
],
],
])
->getBody())
->data;
The product I'm trying to add has no options or modifiers, so I don't understand what could wrong with my request. According to the docs, this should be all that's needed.
Does anyone have any idea what could be wrong? I tried contacting support, but to no avail.
Thanks in advance!
line_items is an array of objects. Try wrapping your product data in an object.
Like this:
'line_items' => [
{
'quantity' => 1,
'product_id' => 86
}
]
Your line_items field needs to have an array of objects, like this:
[
{
"product_id":86,
"quantity":1
}
]

Is there any method in brain-tree auto renew payment?

HI I am using braintree(braintree/braintree_php": "4.5.0) . I have implemented the 3dsecure in the web.It working fine. I need to auto renew the payment with paymentMethodToken. Below code i have used for auto renewal.
$trans = [
'amount' => "14.63",
'merchantAccountId' => "Vo**ID",
'paymentMethodToken' =>"token",
'transactionSource' => "recurring",
'customFields' => [
'client_id' => "id",
'service_id' => "id",
'invoice_id' => "id",
'action' => "autorenew",
'slots' => "15",
],
'options' => [
'submitForSettlement' => true,
'storeInVaultOnSuccess' => true,
'paypal' => [
'description' =>"Renew server",
]
]
];
$transaction = $gateway->transaction()->sale($trans);
When run this code i get below error
Authorization in Util.php line 59:
The above code is working when the user enter the credit card information to pay.This only gives error when i do payment with paymentMethodToken to auto renew the payments.Any help?
reference : https://developers.braintreepayments.com/guides/paypal/server-side/php
As per I understood your requirement. You need to do auto payment.
For that, Braintree provide the best way to do this called Subscription.
Let me know, If you need any more help.

How to get the ID out of Braintree's JSON response?

I'm trying to integrate PayPal Express Checkout using Braintree SDK.
I can so far charge the Nonce returned from the client and I receive this response. However, I need to take the ID out in order to save it in a table.
My question is how do I parse the id??
Successful {#315
+success: true
-_returnObjectNames: array:1 [
0 => "transaction"
]
#_attributes: []
+"transaction": Transaction {#324
#_attributes: array:63 [
"id" => "xxx"// How do I parse this out?
"status" => "settling"
"type" => "sale"
"currencyIsoCode" => "USD"
"amount" => "6.00"
The variable that holds this JSON is $success. Thus, I tried several things like:
$success->transaction->id
$success->id
If I do $success->success I get true and If I do $success->transaction I get the Transaction object.
Full disclosure: I work at Braintree. If you have any further questions, feel free to contact
support.
If running $success->successreturns True and $success->transaction returns the Transaction object, then you should be able to query the transaction ID using $success->transaction->id, we also demonstrate this in our developer documentation.
$result = $gateway->transaction()->sale([
'amount' => '10.00',
'paymentMethodNonce' => nonceFromTheClient,
'options' => [
'submitForSettlement' => True
]
]);
if ($result->success) {
// See $result->transaction for details
} else {
// Handle errors
}

WePay API response error "payment method does not exist or does not belong to app"

i was having a problem with Wepay API. My codes are correct but it keeps on returning an error saying "payment method does not exist or does not belong to app". I already configured the permission to allow tokenized credit cards. But still. Any feedback is greatly appreciated. Thanks!
Here is my code
require_once('public/payment/wepay/wepay.php');
$user = API::get_client(['fldClientEmail' => $email])->first();
// change to useProduction for live environments
\Wepay::useStaging(WEPAY_CLIENT_ID, WEPAY_CLIENT_SECRET);
$wepay = new \WePay($user->fldClientWepayTokenAccess);
// $wepay = new \WePay(WEPAY_ACCESS_TOKEN);
// dd($email);die;
// dd($user->fldClientWepayAccountID);die;
// charge the credit card
$response = $wepay->request('checkout/create', [
'account_id' => $user->fldClientWepayAccountID,
'amount' => number_format(Input::get('amount_tipped'),2),
'currency' => 'USD',
'short_description' => 'A short description',
'type' => 'goods',
'payment_method' => array(
'type' => 'credit_card',
'credit_card' => array(
'id' => Input::get('cc_id')
)
)
]);
// display the response
return $response;
Make sure that when you follow the tutorial from their docs, you replace all of the credentials from the examples. I was using their Javascript library for the tokenization of the credit card with the client_id they provided.
response = WePay.credit_card.create({
"client_id": YOUR.CLIENT.ID.HERE,
"user_name": valueById('name'),
"email": valueById('email'),
"cc_number": valueById('cc-number'),
"cvv": valueById('cc-cvv'),
"expiration_month": valueById('cc-month'),
"expiration_year": valueById('cc-year'),
"address": {
"postal_code": valueById('postal_code')
}
If you don't provide your own, is like you were creating those credit cards for another application that's not yours.
If this didn't do the trick, check this article, hopefully it does:
https://support.wepay.com/hc/en-us/articles/203609273-WePay-API-Error-Codes

Categories