<p>In the end I worked out the card is related to a customer, not a subscription.</p>

<p>I couldn't see any public endpoint to update a customer's card, so I added this method in <code>charge/controllers/ChargeController.php</code> (not ideal to update the plugin directly I know):</p>

<pre><code>public function actionUpdateCard()
{
  $this-&gt;requirePostRequest();
  $customer = craft()-&gt;charge_customer-&gt;find();
  $cardToken = craft()-&gt;request-&gt;getRequiredPost('cardToken');

  if ($customer-&gt;addCard($cardToken)) {
    $this-&gt;returnJson(['success' =&gt; true]);
  } else {
    $this-&gt;returnJson(['success' =&gt; false]);
  }
}
</code></pre>

<p>and then can make requests to the <code>charge/updateCard</code> endpoint:</p>

<pre><code>getStripeToken(cardToken =&gt; {
  post({
    params: {
      action: 'charge/updateCard',
      cardToken
    },
    then: ({ success }) =&gt; console.log(`Card updated: ${success}`)
    url: '/'
  })
})
</code></pre>

CC BY-SA 3.0
2017-10-05T17:04:32.313Z
2017-10-06T12:35:58.240Z
2017-10-06T12:35:58.240Z
Colin Meinke
<p>I am attempting to create a form where the user can update their subscription card details (with Stripe Elements).</p>

<p>From looking at the Charge plugin's source code, I believe the endpoint I need is <code>charge/updateSubscription</code>.</p>

<p>As with checkout I am creating an opts hidden input in my twig template like so:</p>

<pre><code>{{
  craft.charge.setPaymentOptions({
    planAmount: currentSubscription.planAmount,
    planInterval: currentSubscription.planInterval,
    planIntervalCount: currentSubscription.planIntervalCount
  })
}}
</code></pre>

<p>And then making a POST request with Javascript to the endpoint:</p>

<pre><code>getStripeToken(cardToken =&gt; {
  post({
    params: {
      action: 'charge/updateSubscription',
      opts,
      cardToken,
      subscriptionId
    },
    then: response =&gt; console.log(response)
    url: '/'
  })
})
</code></pre>

<p>Quite simply, this doesn't work. I receive a <code>{success: true}</code> response, but the Stripe card has not been updated.</p>

<p>Does anybody what I'm doing wrong, or even if this is possible?</p>

<plugins><plugin-charge><stripe>
Charge: Update subscription card details
# Charge: Update subscription card details

(Asked by: username_0 on 2017-10-05)

I am attempting to create a form where the user can update their subscription card details (with Stripe Elements).
From looking at the Charge plugin's source code, I believe the endpoint I need is charge/updateSubscription.
As with checkout I am creating an opts hidden input in my twig template like so:
{{
  craft.charge.setPaymentOptions({
    planAmount: currentSubscription.planAmount,
    planInterval: currentSubscription.planInterval,
    planIntervalCount: currentSubscription.planIntervalCount
  })
}}

And then making a POST request with Javascript to the endpoint:
getStripeToken(cardToken => {
  post({
    params: {
      action: 'charge/updateSubscription',
      opts,
      cardToken,
      subscriptionId
    },
    then: response => console.log(response)
    url: '/'
  })
})

Quite simply, this doesn't work. I receive a {success: true} response, but the Stripe card has not been updated.
Does anybody what I'm doing wrong, or even if this is possible?

**Tags:** plugins, plugin-charge, stripe

---

## 1 answers

### Answer by username_0 on 2017-10-05. Score: 4 | Accepted answer

In the end I worked out the card is related to a customer, not a subscription.
I couldn't see any public endpoint to update a customer's card, so I added this method in charge/controllers/ChargeController.php (not ideal to update the plugin directly I know):
public function actionUpdateCard()
{
  $this->requirePostRequest();
  $customer = craft()->charge_customer->find();
  $cardToken = craft()->request->getRequiredPost('cardToken');

  if ($customer->addCard($cardToken)) {
    $this->returnJson(['success' => true]);
  } else {
    $this->returnJson(['success' => false]);
  }
}

and then can make requests to the charge/updateCard endpoint:
getStripeToken(cardToken => {
  post({
    params: {
      action: 'charge/updateCard',
      cardToken
    },
    then: ({ success }) => console.log(`Card updated: ${success}`)
    url: '/'
  })
})


---

