Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-10-05T17:04:32.313Z
Answers.LastActivityDate: 2017-10-06T12:35:58.240Z
Answers.LastEditDate: 2017-10-06T12:35:58.240Z
Answers.UserDisplayName: Colin Meinke
Body: <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>
  
Tags: <plugins><plugin-charge><stripe>
Title: Charge: Update subscription card details
ThreadText: # 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: '/'
    })
  })
  
  ```
  
  
  ---
  
  