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

# Ortak Ödeme Sayfası

> Modern ödeme altyapısı için güçlü ve esnek API çözümü

Tahsilat.js SDK, herhangi bir backend altyapısı gerektirmeden, doğrudan tarayıcı üzerinden güvenli ödeme işlemleri başlatmanıza olanak tanır. SDK, PCI-DSS uyumlu ödeme formlarını iframe veya redirect yöntemiyle entegre etmenizi sağlar.

<Note>
  Tahsilat.js, modern web uygulamalarında ödeme entegrasyonunu kolaylaştıran güçlü bir JavaScript SDK'dır. Hassas kart bilgilerinin hiçbir zaman sunucularınızdan geçmemesini sağlayarak PCI uyumluluk yükünüzü minimize eder.
</Note>

<Warning>
  Entegrasyon sürecinde hata takibi için tarayıcı konsolunu takip ediniz.
</Warning>

<Info>
  Ödeme tutarı ile ürünler arasındaki toplam tutarın eşleşmesi gerekmektedir. Aksi takdirde, ödeme reddedilir.
</Info>

Tahsilat JS sadece "Public Key" ile çalışır. Entegrasyon aşamasında isterseniz herhangi bir div elementine ödeme formunu yerleştirebilir ya da `redirectToPayment` metodu ile direkt ödeme sayfasına yönlendirebilirsiniz. Ödeme formu, Tahsilat.js SDK tarafından sağlanan `payment` elementi ile oluşturulur.

### 1. Direkt Ödeme

Ürün ya da müşteri bilgisi belirtmeden doğrudan ödeme isteği tanımlayabilirsiniz:

<CodeGroup>
  ```js JS theme={null}
  const tahsilat = new TahsilatSDK('pk_test_wsg...');
  const elements = tahsilat.elements();

  const paymentElement = elements.create('payment', {
      amount: 10000,
      metadata: [
          { key: "order_id", value: "123456" },
          { key: "customer_type", value: "premium" }
      ],
  });

  // İlgili element içine ödeme formunu yerleştirin
  paymentElement.mount('#payment-element');
  ```
</CodeGroup>

### 2. Doğrudan Ürün Bilgileri ile Ödeme

Ürün bilgilerini doğrudan ödeme isteği içerisinde tanımlayabilirsiniz:

<CodeGroup>
  ```js JS theme={null}
  const tahsilat = new TahsilatSDK('pk_test_wsg...');
  const elements = tahsilat.elements();

  const paymentElement = elements.create('payment', {
      amount: 10000,
      products: [
          {
              product_name: 'Test Product',
              price: 10000,
              description: "This is a test product"
          }
      ],
      metadata: [
          { key: "order_id", value: "123456" },
          { key: "customer_type", value: "premium" }
      ],
  });

  // İlgili element içine ödeme formunu yerleştirin
  paymentElement.mount('#payment-element');
  ```
</CodeGroup>

### 3. Ürün ID'leri ile Ödeme

Önceden oluşturulmuş ürünlerin ID'lerini kullanarak ödeme başlatabilirsiniz bu durumda ürünleriniz hakkında raporlama ve analiz yapabilirsiniz:

Ürün oluşturmak için [Ürünler](../api-reference/products) sayfasını ziyaret edebilirsiniz.

<CodeGroup>
  ```js JS theme={null}
  const tahsilat = new TahsilatSDK('pk_test_wsg...');
  const elements = tahsilat.elements();

  const paymentElement = elements.create('payment', {
      amount: 10000,
      product_ids: ['11111111111111', '2222222222222'],
      metadata: [
          { key: "order_id", value: "123456" },
          { key: "customer_type", value: "premium" }
      ],
  });

  // İlgili element içine ödeme formunu yerleştirin
  paymentElement.mount('#payment-element');
  ```
</CodeGroup>

### 4. Müşteri ile İlişkilendirilmiş Ödeme

Mevcut bir müşteriyi ödeme ile ilişkilendirmek için `customer_id` parametresini kullanabilirsiniz. Bu durumda ödeme esnasında müşteri bilgileri tekrardan alınmaz:

Müşteri oluşturmak için [Müşteriler](../api-reference/customers) sayfasını ziyaret edebilirsiniz.

<CodeGroup>
  ```js JS theme={null}
  const tahsilat = new TahsilatSDK('pk_test_wsg...');
  const elements = tahsilat.elements();

  const paymentElement = elements.create('payment', {
      amount: 10000,
      customer_id: 123456789,
      product_ids: ['11111111111111', '2222222222222'],
      metadata: [
          { key: "order_id", value: "123456" },
          { key: "customer_type", value: "premium" }
      ],
  });

  // İlgili element içine ödeme formunu yerleştirin
  paymentElement.mount('#payment-element');
  ```
</CodeGroup>

### 5. Direkt Ödeme Yönlendirme

Tahsilat.js SDK, ödeme işlemlerini doğrudan Tahsilat ödeme sayfasına yönlendirme sunar. Bu yöntem, iframe kullanmadan, kullanıcıyı Tahsilat ödeme sayfasına yönlendirerek ödeme işlemini başlatmanızı sağlar.

<CodeGroup>
  ```js JS theme={null}
  const tahsilat = new TahsilatSDK('pk_test_wsg...');

  async function initiatePayment() {
      try {
          await tahsilat.redirectToPayment({
              amount: 61900,
              products: [
                  {
                      product_name: 'Test Product',
                      price: 61900,
                      description: "This is a test product"
                  }
              ],
              metadata: [
                  { key: "order_id", value: "123456" },
                  { key: "customer_type", value: "premium" }
              ],
          });
      } catch (error) {
          console.error('Ödeme hatası:', error);
      }
  }

  initiatePayment();
  ```
</CodeGroup>

<Warning>
  Ödeme isteği oluşturulurken customer\_id gönderilmemesi durumunda her ödeme için müşteri bilgileri tekrar alınır ve yeni bir müşteri oluşturulur. Bu durumda müşteri takibi ve raporlama süreci zorlaşabilir.

  Üye işyeri arayüzünden ya da [Müşteriler](../api-reference/customers) sayfasından api aracılığı ile müşteri oluşturarak customer\_id parametresini kullanabilirsiniz.
</Warning>

<Warning>
  Ödeme sonuçlarını alabilmek için backend tarafında Tahsilat API ile entegre olabilir ya da direkt post message sonuçlarını dinleyebilirsiniz. Webhook olayları en güvenilir yöntemdir.
</Warning>

### Ödeme Sonuçlarını Dinleme

Tahsilat.js SDK, ödeme işlemlerinin sonuçlarını event listener'lar aracılığıyla yakalamanızı sağlar. Bu sayede ödeme başarılı, başarısız veya iptal edildiğinde kullanıcıya bilgi verebilir ve gerekli aksiyonları alabilirsiniz.

<Warning>
  Eğer ödemeyi `pre_auth: true` ile başlattıysanız, sonuç aldığınızda **is\_pre\_auth** değerini kontrol edin. `true` dönmesi durumunda ödeme başarılıdır ancak tutar karttan çekilmemiş, yalnızca bloke edilmiştir. Bloke edilen tutarı çekmek için ayrıca **ön provizyonu kapatma** işlemi yapmanız gerekmektedir.
</Warning>

<CodeGroup>
  ```js Temel Kullanım theme={null}
  const tahsilat = new TahsilatSDK('pk_test_wsg...');
  const elements = tahsilat.elements();

  const paymentElement = elements.create('payment', {
      amount: 10000,
      metadata: [
          { key: "order_id", value: "123456" }
      ],
  });

  // Başarılı ödeme
  tahsilat.on('paymentSuccess', function(data) {
      console.log('Ödeme başarılı:', data);
      // Örnek: Teşekkür sayfasına yönlendir
  });

  // Başarısız ödeme
  tahsilat.on('paymentError', function(data) {
      console.log('Ödeme hatası:', data);
      // Örnek: Kullanıcıya hata mesajı göster
  });

  // İptal edilen ödeme
  tahsilat.on('paymentCancelled', function(data) {
      console.log('Ödeme iptal edildi:', data);
      // Örnek: Sepet sayfasına yönlendir
  });

  // Ödeme formunu yerleştir
  paymentElement.mount('#payment-element');
  ```

  ```json Başarılı Yanıt theme={null}
  {
      "success": true,
      "transaction_id": "21325480405674",
      "payment_status": 1,
      "transaction_status": 2,
      "is_pre_auth": false,
      "amount": 50000,
      "currency": "TRY",
      "message": "İşleminiz başarılı bir şekilde tamamlanmıştır.",
      "error_code": "",
      "metadata": [
          { "key": "order_id", "value": "123456" },
          { "key": "customer_type", "value": "premium" }
      ]
  }
  ```

  ```json Başarısız Yanıt theme={null}
  {
      "success": false,
      "transaction_id": "20544083688242",
      "payment_status": 2,
      "transaction_status": 2,
      "is_pre_auth": false,
      "amount": 50000,
      "currency": "TRY",
      "message": "Hatalı test kart bilgisi.",
      "error_code": "invalid_test_card",
      "metadata": [
          { "key": "order_id", "value": "123456" },
          { "key": "customer_type", "value": "premium" }
      ]
  }
  ```

  ```js Opsiyonel Event'ler theme={null}
  // 3D Secure yönlendirmesi başladığında
  tahsilat.on('3dsRedirect', function(data) {
      console.log('3DS yönlendirmesi başladı:', data);
      // Bilgilendirme amaçlı kullanılabilir
  });

  // Ödeme işleme alındığında
  tahsilat.on('paymentProcessing', function(data) {
      console.log('Ödeme işleniyor:', data);
      // Loading göstergesi için kullanılabilir
  });
  ```
</CodeGroup>

### Yanıt Alanları

| Alan                 | Tip     | Açıklama                                  |
| -------------------- | ------- | ----------------------------------------- |
| `success`            | boolean | İşlem başarılı mı                         |
| `transaction_id`     | string  | Tahsilat işlem numarası                   |
| `payment_status`     | integer | `1`: Başarılı, `2`: Başarısız             |
| `transaction_status` | integer | `2`: Tamamlandı, `3`: Ön provizyon        |
| `is_pre_auth`        | boolean | Ön provizyon işlemi mi                    |
| `amount`             | integer | Tutar (kuruş)                             |
| `currency`           | string  | Para birimi                               |
| `message`            | string  | Durum mesajı                              |
| `error_code`         | string  | Hata kodu (başarısızsa)                   |
| `metadata`           | array   | Ödeme başlatılırken gönderilen ek veriler |

## Zorunlu ve İsteğe Bağlı Parametreler

<ResponseField name="customer_id" type="integer">
  Ödeme ile ilişkilendirilecek müşteri ID'si. Bu parametre isteğe bağlıdır, ancak müşteri takibi için önerilir.
</ResponseField>

<ResponseField name="amount" type="integer" required>
  Ödeme tutarı, kuruş cinsinden belirtilmelidir. Örneğin, 10.00 TL için 1000 olarak girilmelidir. Son 2 hane her zaman kuruş olarak kabul edilir.
</ResponseField>

<ResponseField name="currency" type="string" required>
  Ödeme para birimi. 3 haneli ISO 4217 kodu olarak belirtilmelidir (örn. "TRY" - Türk Lirası). Varsayılan değer "TRY"dir.
</ResponseField>

<ResponseField name="pre_auth" type="bool">
  Ödeme ön provizyon olarak başlatılacaksa true, normal ödeme için false olarak belirtilmelidir. Varsayılan değer false'dir.
</ResponseField>

<ResponseField name="products" type="array" required>
  Ödeme ile ilişkilendirilecek ürünlerin bilgilerini içeren JSON string formatında dizi. Eğer `product_ids` gönderilmiyorsa, bu parametre zorunludur.

  **Format:** JSON string olarak gönderilmelidir.

  **Ürün alanları:**

  * `product_name` (string, zorunlu): Ürün adı
  * `price` (integer, zorunlu): Ürün fiyatı (kuruş cinsinden)
  * `description` (string, isteğe bağlı): Ürün açıklaması

  **Örnek:**

  ```
  products=[{"product_name":"Premium Üyelik","price":10000,"description":"Aylık premium üyelik"}]
  ```

  **Birden fazla ürün:**

  ```
  products=[{"product_name":"Ürün 1","price":5000},{"product_name":"Ürün 2","price":3000}]
  ```
</ResponseField>

<ResponseField name="product_ids" type="array" required>
  Ödeme ile ilişkilendirilecek ürünlerin ID'lerini içeren dizi. Eğer products gönderilmiyorsa, bu parametre zorunludur. Her ürün için Tahsilat API'de önceden oluşturulmuş ürün ID'leri kullanılmalıdır.
</ResponseField>

<ResponseField name="metadata" type="array">
  Ödeme ile ilişkilendirilecek ek verileri içeren dizi. Bu parametre isteğe bağlıdır, ancak ödeme raporlaması için önerilir. Örneğin, müşteri türü gibi bilgiler burada saklanabilir.
</ResponseField>

<ResponseField name="description" type="string">
  Ödeme ile ilgili açıklama. Bu parametre isteğe bağlıdır ve ödeme hakkında ek bilgi sağlamak için kullanılabilir.
</ResponseField>

<div className="panels">
  <Panel>
    <CodeGroup>
      ```md JS theme={null}
      https://js.tahsilat.com/v1/tahsilat.js
      ```
    </CodeGroup>

    <br />

    İstek

    <CodeGroup>
      ```js JS theme={null}
      const tahsilat = new TahsilatSDK('pk_test_wsg...');
      const elements = tahsilat.elements();

      const paymentElement = elements.create('payment', {
          amount: 10000,
          metadata: [
            { key: "order_id", value: "123456" },
            { key: "customer_type", value: "premium" }
          ],
      });

      // İlgili element içine ödeme formunu yerleştirin
      paymentElement.mount('#payment-element');
      ```
    </CodeGroup>

    <br />

    Direkt Ödeme Yönlendirme

    <Info>
      Bu yöntem müşteriyi doğrudan Tahsilat ödeme sayfasına yönlendirir.
    </Info>

    <CodeGroup>
      ```js JS theme={null}
      const tahsilat = new TahsilatSDK('pk_test_wsg...');

      async function initiatePayment() {
          try {
              await tahsilat.redirectToPayment({
                  amount: 61900,
                  metadata: [
                    { key: "order_id", value: "123456" },
                    { key: "customer_type", value: "premium" }
                  ],
              });
          } catch (error) {
              console.error('Ödeme hatası:', error);
          }
      }

      initiatePayment();
      ```
    </CodeGroup>

    <Note>
      Tahsilat JS yalnızca public key ile çalışır. Public key'i güvenle mobil ve web uygulamalarınızda kullanabilirsiniz.
      Secret key'i asla istemci tarafında kullanmayın; yalnızca arka uçta kullanılmalıdır.
    </Note>
  </Panel>
</div>
