> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dodopayments.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Perbarui Metode Pembayaran

> Perbarui metode pembayaran untuk langganan yang ada. Anda dapat menambahkan metode pembayaran baru atau menggunakan yang sudah ada dari metode pembayaran yang disimpan oleh pelanggan.

Perbarui metode pembayaran untuk langganan. Endpoint ini mendukung baik langganan aktif maupun langganan dalam kondisi `on_hold`.

<Info>
  Untuk langganan dalam status `on_hold`, memperbarui metode pembayaran secara otomatis membuat tagihan untuk tunggakan yang tersisa, menghasilkan faktur, dan mengaktifkan kembali langganan ke status `active` setelah pembayaran berhasil.
</Info>

### Kasus Penggunaan

* **Langganan aktif**: Perbarui metode pembayaran ketika kartu kedaluwarsa atau pelanggan ingin menggunakan metode pembayaran yang berbeda
* **Langganan ditangguhkan**: Mengaktifkan kembali langganan yang ditangguhkan karena pembayaran gagal dengan memperbarui metode pembayaran
* **Manajemen metode pembayaran**: Beralih antara metode pembayaran yang disimpan atau menambahkan yang baru

<Info>
  Untuk menampilkan metode pembayaran yang tersedia untuk pelanggan, gunakan [List Payment Methods API](/api-reference/customers/get-customer-payment-methods). Ini membantu Anda mengambil ID metode pembayaran yang tersedia saat menggunakan `type: "existing"` untuk memperbarui metode pembayaran langganan.
</Info>

### Perilaku untuk Langganan Aktif

Saat memperbarui metode pembayaran untuk langganan aktif:

* Metode pembayaran diperbarui segera
* Tidak ada biaya yang dibuat
* Langganan tetap aktif
* Pembaruan di masa depan akan menggunakan metode pembayaran baru

### Perilaku untuk Langganan Ditangguhkan

Saat memperbarui metode pembayaran untuk langganan dalam status `on_hold`:

1. Biaya secara otomatis dibuat untuk tunggakan yang tersisa
2. Faktur dibuat untuk biaya tersebut
3. Pembayaran diproses menggunakan metode pembayaran baru
4. Setelah pembayaran berhasil, langganan diaktifkan kembali ke status `active`
5. Anda akan menerima event webhook: `payment.succeeded` diikuti oleh `subscription.active`

<Warning>
  Jika pembayaran gagal setelah memperbarui metode pembayaran untuk langganan `on_hold`, langganan akan tetap dalam status `on_hold`. Pantau event webhook untuk melacak status pembayaran.
</Warning>

### Peristiwa Webhook

Saat memperbarui metode pembayaran untuk langganan `on_hold`, Anda akan menerima event webhook berikut:

1. **`payment.succeeded`** - Biaya untuk tunggakan berhasil
2. **`subscription.active`** - Langganan telah diaktifkan kembali


## OpenAPI

````yaml post /subscriptions/{subscription_id}/update-payment-method
openapi: 3.1.0
info:
  title: public
  description: ''
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0
  version: 1.106.2
servers:
  - url: https://test.dodopayments.com/
    description: Test Mode Server Host
  - url: https://live.dodopayments.com/
    description: Live Mode Server Host
security: []
tags:
  - name: Products
  - name: Payments
  - name: Subscriptions
  - name: Addons
  - name: Customers
  - name: Refunds
  - name: Disputes
  - name: Events
  - name: License Keys
  - name: Entitlements
  - name: Licenses
  - name: Discounts
  - name: Meters
  - name: Credit Entitlements
  - name: Credit Entitlement Balances
  - name: Outgoing Webhooks
  - name: Checkout
  - name: Webhook Events
  - name: Payment Connector Webhooks
paths:
  /subscriptions/{subscription_id}/update-payment-method:
    post:
      tags:
        - Subscriptions
      operationId: update
      parameters:
        - name: subscription_id
          in: path
          description: Subscription Id
          required: true
          schema:
            type: string
          example: sub_Iuaq622bbmmfOGrVTqdXv
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdatePaymentMethodReq'
        required: true
      responses:
        '200':
          description: Payment method updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UpdatePaymentMethodResponse'
        '422':
          description: Invalid Request Object or Parameters
        '500':
          description: Something went wrong :(
      security:
        - API_KEY: []
      x-codeSamples:
        - lang: JavaScript
          source: >-
            import DodoPayments from 'dodopayments';


            const client = new DodoPayments({
              bearerToken: process.env['DODO_PAYMENTS_API_KEY'], // This is the default and can be omitted
            });


            const response = await
            client.subscriptions.updatePaymentMethod('sub_Iuaq622bbmmfOGrVTqdXv',
            {
              payment_method: { type: 'new' },
            });


            console.log(response.payment_id);
        - lang: Python
          source: |-
            import os
            from dodopayments import DodoPayments

            client = DodoPayments(
                bearer_token=os.environ.get("DODO_PAYMENTS_API_KEY"),  # This is the default and can be omitted
            )
            response = client.subscriptions.update_payment_method(
                subscription_id="sub_Iuaq622bbmmfOGrVTqdXv",
                payment_method={
                    "type": "new"
                },
            )
            print(response.payment_id)
        - lang: Go
          source: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/dodopayments/dodopayments-go\"\n\t\"github.com/dodopayments/dodopayments-go/option\"\n)\n\nfunc main() {\n\tclient := dodopayments.NewClient(\n\t\toption.WithBearerToken(\"My Bearer Token\"),\n\t)\n\tresponse, err := client.Subscriptions.UpdatePaymentMethod(\n\t\tcontext.TODO(),\n\t\t\"sub_Iuaq622bbmmfOGrVTqdXv\",\n\t\tdodopayments.SubscriptionUpdatePaymentMethodParams{\n\t\t\tPaymentMethod: dodopayments.SubscriptionUpdatePaymentMethodParamsPaymentMethodNew{\n\t\t\t\tType: dodopayments.F(dodopayments.SubscriptionUpdatePaymentMethodParamsPaymentMethodNewTypeNew),\n\t\t\t},\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", response.PaymentID)\n}\n"
        - lang: Java
          source: >-
            package com.dodopayments.api.example;


            import com.dodopayments.api.client.DodoPaymentsClient;

            import com.dodopayments.api.client.okhttp.DodoPaymentsOkHttpClient;

            import
            com.dodopayments.api.models.subscriptions.SubscriptionUpdatePaymentMethodParams;

            import
            com.dodopayments.api.models.subscriptions.SubscriptionUpdatePaymentMethodResponse;


            public final class Main {
                private Main() {}

                public static void main(String[] args) {
                    DodoPaymentsClient client = DodoPaymentsOkHttpClient.fromEnv();

                    SubscriptionUpdatePaymentMethodParams params = SubscriptionUpdatePaymentMethodParams.builder()
                        .subscriptionId("sub_Iuaq622bbmmfOGrVTqdXv")
                        .paymentMethod(SubscriptionUpdatePaymentMethodParams.PaymentMethod.New.builder().build())
                        .build();
                    SubscriptionUpdatePaymentMethodResponse response = client.subscriptions().updatePaymentMethod(params);
                }
            }
        - lang: Kotlin
          source: >-
            package com.dodopayments.api.example


            import com.dodopayments.api.client.DodoPaymentsClient

            import com.dodopayments.api.client.okhttp.DodoPaymentsOkHttpClient

            import
            com.dodopayments.api.models.subscriptions.SubscriptionUpdatePaymentMethodParams

            import
            com.dodopayments.api.models.subscriptions.SubscriptionUpdatePaymentMethodResponse


            fun main() {
                val client: DodoPaymentsClient = DodoPaymentsOkHttpClient.fromEnv()

                val params: SubscriptionUpdatePaymentMethodParams = SubscriptionUpdatePaymentMethodParams.builder()
                    .subscriptionId("sub_Iuaq622bbmmfOGrVTqdXv")
                    .paymentMethod(SubscriptionUpdatePaymentMethodParams.PaymentMethod.New.builder().build())
                    .build()
                val response: SubscriptionUpdatePaymentMethodResponse = client.subscriptions().updatePaymentMethod(params)
            }
        - lang: Ruby
          source: |-
            require "dodopayments"

            dodo_payments = Dodopayments::Client.new(
              bearer_token: "My Bearer Token",
              environment: "test_mode" # defaults to "live_mode"
            )

            response = dodo_payments.subscriptions.update_payment_method(
              "sub_Iuaq622bbmmfOGrVTqdXv",
              payment_method: {type: :new}
            )

            puts(response)
        - lang: PHP
          source: |-
            <?php

            require_once dirname(__DIR__) . '/vendor/autoload.php';

            use Dodopayments\Client;
            use Dodopayments\Core\Exceptions\APIException;
            use Dodopayments\Payments\PaymentMethodTypes;

            $client = new Client(
              bearerToken: getenv('DODO_PAYMENTS_API_KEY') ?: 'My Bearer Token',
              environment: 'test_mode',
            );

            try {
              $response = $client->subscriptions->updatePaymentMethod(
                'sub_Iuaq622bbmmfOGrVTqdXv',
                paymentMethod: [
                  'type' => 'new',
                  'allowedPaymentMethodTypes' => [PaymentMethodTypes::ACH],
                  'returnURL' => 'return_url',
                ],
              );

              var_dump($response);
            } catch (APIException $e) {
              echo $e->getMessage();
            }
        - lang: C#
          source: >-
            using System;

            using DodoPayments.Client;

            using DodoPayments.Client.Models.Payments;

            using DodoPayments.Client.Models.Subscriptions;


            DodoPaymentsClient client = new();


            SubscriptionUpdatePaymentMethodParams parameters = new()

            {
                SubscriptionID = "sub_Iuaq622bbmmfOGrVTqdXv",
                PaymentMethod = new New()
                {
                    AllowedPaymentMethodTypes =
                    [
                        PaymentMethodTypes.Ach
                    ],
                    ReturnUrl = "return_url",
                },
            };


            var response = await
            client.Subscriptions.UpdatePaymentMethod(parameters);


            Console.WriteLine(response);
        - lang: Rust
          source: |-
            use dodopayments::Client;

            #[tokio::main]
            async fn main() -> dodopayments::Result<()> {
                let client = Client::from_env()?;
                let subscription_id = "subscription_id";
                let result = client
                    .subscriptions()
                    .update_payment_method()
                    .subscription_id(subscription_id)
                    .body(serde_json::json!({"type":"new","allowed_payment_method_types":["ach"],"return_url":"return_url"}))
                    .await?;
                println!("{result:?}");
                Ok(())
            }
components:
  schemas:
    UpdatePaymentMethodReq:
      oneOf:
        - type: object
          title: New
          required:
            - type
          properties:
            allowed_payment_method_types:
              type:
                - array
                - 'null'
              items:
                $ref: '#/components/schemas/PaymentMethodTypes'
              description: >-
                List of payment methods allowed during checkout.


                Customers will **never** see payment methods that are **not** in
                this list.

                However, adding a method here **does not guarantee** customers
                will see it.

                Availability still depends on other factors (e.g., customer
                location, merchant settings).
              uniqueItems: true
            return_url:
              type:
                - string
                - 'null'
            type:
              type: string
              enum:
                - new
              x-stainless-const: true
        - type: object
          title: Existing
          required:
            - payment_method_id
            - type
          properties:
            payment_method_id:
              type: string
            type:
              type: string
              enum:
                - existing
              x-stainless-const: true
      discriminator:
        propertyName: type
    UpdatePaymentMethodResponse:
      type: object
      properties:
        client_secret:
          type:
            - string
            - 'null'
        expires_on:
          type:
            - string
            - 'null'
          format: date-time
        payment_id:
          type:
            - string
            - 'null'
        payment_link:
          type:
            - string
            - 'null'
    PaymentMethodTypes:
      type: string
      description: |-
        All supported payment method types.

        Used for disabled-payment-methods filtering and validation.
      enum:
        - ach
        - affirm
        - afterpay_clearpay
        - alfamart
        - ali_pay
        - ali_pay_hk
        - alma
        - amazon_pay
        - apple_pay
        - atome
        - bacs
        - bancontact_card
        - becs
        - benefit
        - bizum
        - blik
        - boleto
        - bca_bank_transfer
        - bni_va
        - bri_va
        - card_redirect
        - cimb_va
        - classic
        - credit
        - crypto_currency
        - cashapp
        - dana
        - danamon_va
        - debit
        - duit_now
        - efecty
        - eft
        - eps
        - fps
        - evoucher
        - giropay
        - givex
        - google_pay
        - go_pay
        - gcash
        - ideal
        - interac
        - indomaret
        - klarna
        - kakao_pay
        - local_bank_redirect
        - mandiri_va
        - knet
        - mb_way
        - mobile_pay
        - momo
        - momo_atm
        - multibanco
        - online_banking_thailand
        - online_banking_czech_republic
        - online_banking_finland
        - online_banking_fpx
        - online_banking_poland
        - online_banking_slovakia
        - oxxo
        - pago_efectivo
        - permata_bank_transfer
        - open_banking_uk
        - pay_bright
        - paypal
        - paze
        - pix
        - pay_safe_card
        - przelewy24
        - prompt_pay
        - pse
        - red_compra
        - red_pagos
        - samsung_pay
        - sepa
        - sepa_bank_transfer
        - sofort
        - sunbit
        - swish
        - touch_n_go
        - trustly
        - twint
        - upi_collect
        - upi_intent
        - vipps
        - viet_qr
        - venmo
        - walley
        - we_chat_pay
        - seven_eleven
        - lawson
        - mini_stop
        - family_mart
        - seicomart
        - pay_easy
        - local_bank_transfer
        - mifinity
        - open_banking_pis
        - direct_carrier_billing
        - instant_bank_transfer
        - billie
        - zip
        - revolut_pay
        - naver_pay
        - payco
        - satispay
  securitySchemes:
    API_KEY:
      type: http
      scheme: bearer

````