Answers.Body: <p>I think matt spearheaded this feature, in any case, he's implemented it for stripe, here: <a href="https://lab.civicrm.org/extensions/stripe/-/blob/master/CRM/Core/Payment/Stripe.php" rel="nofollow noreferrer">https://lab.civicrm.org/extensions/stripe/-/blob/master/CRM/Core/Payment/Stripe.php</a></p>
  <p>That implementation looks like it's expecting a transaction id, which is usually exactly what you need (since that should be a unique identifier of the transaction and shared/stored with the payment processor).</p>
  <p>What you're seeing in the api3 endpoint is just some code that checks if the processor supports refunds, before passing through whatever parameters it got.</p>
  <p>TBH, I've avoided implementing it, due to the risk of bad things happening unintentionally.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-11-25T17:02:33.013Z
Answers.LastActivityDate: 2024-11-25T17:02:33.013Z
Answers.UserDisplayName: Alan Dixon
Body: <p>I created a custom payment processor with its <a href="https://docs.civicrm.org/dev/en/latest/extensions/payment-processors/paymentclass/" rel="nofollow noreferrer">Payment class</a>.</p>
  <p>Now, I want to implement the refund feature, based on the <a href="https://docs.civicrm.org/dev/en/latest/extensions/payment-processors/paymentclass/#dorefund-function" rel="nofollow noreferrer">doRefund</a> method, but I can't figure how to catch a refund action.</p>
  <pre><code>  /**
     * Refunds payment
     *
     * @param array $params
     *
     * @return array
     *   Result array (containing at least the key refund_status)
     */
    public function doRefund(&amp;$params) {
      return ['refund_status' =&gt; 'Completed'];
    }
  </code></pre>
  <p>After investigations in CiviCRM Core, <code>doRefund()</code> is called in one unique place :
  <code>civicrm/api/v3/PaymentProcessor.php</code> which is an API3 endpoint</p>
  <pre><code>/**
   * Action refund.
   *
   * @param array $params
   *
   * @return array
   *   API result array.
   *
   * @throws \CRM_Core_Exception
   * @throws \Civi\Payment\Exception\PaymentProcessorException
   */
  function civicrm_api3_payment_processor_refund($params) {
    /** @var \CRM_Core_Payment $processor */
    $processor = Civi\Payment\System::singleton()-&gt;getById($params['payment_processor_id']);
    $processor-&gt;setPaymentProcessor(civicrm_api3('PaymentProcessor', 'getsingle', ['id' =&gt; $params['payment_processor_id']]));
    if (!$processor-&gt;supportsRefund()) {
      throw new CRM_Core_Exception('Payment Processor does not support refund');
    }
    $result = $processor-&gt;doRefund($params);
    return civicrm_api3_create_success([$result], $params);
  }
  </code></pre>
  <p>This endpoint only get two params:</p>
  <ul>
  <li>payment_processor_id</li>
  <li>amount</li>
  </ul>
  <p>I guess, it's just a proof of concept because data are insufficient to create any transaction.</p>
  <p>Is there any implementations of it?</p>
  
Tags: <api><payment-processor><refund>
Title: What is the purpose of the doRefund() method in a Payment class?
ThreadText: # What is the purpose of the doRefund() method in a Payment class?
  
  (Asked by: username_0 on 2024-11-21)
  
  I created a custom payment processor with its Payment class.
  Now, I want to implement the refund feature, based on the doRefund method, but I can't figure how to catch a refund action.
    /**
     * Refunds payment
     *
     * @param array $params
     *
     * @return array
     *   Result array (containing at least the key refund_status)
     */
    public function doRefund(&$params) {
      return ['refund_status' => 'Completed'];
    }
  
  After investigations in CiviCRM Core, doRefund() is called in one unique place :
  civicrm/api/v3/PaymentProcessor.php which is an API3 endpoint
  /**
   * Action refund.
   *
   * @param array $params
   *
   * @return array
   *   API result array.
   *
   * @throws \CRM_Core_Exception
   * @throws \Civi\Payment\Exception\PaymentProcessorException
   */
  function civicrm_api3_payment_processor_refund($params) {
    /** @var \CRM_Core_Payment $processor */
    $processor = Civi\Payment\System::singleton()->getById($params['payment_processor_id']);
    $processor->setPaymentProcessor(civicrm_api3('PaymentProcessor', 'getsingle', ['id' => $params['payment_processor_id']]));
    if (!$processor->supportsRefund()) {
      throw new CRM_Core_Exception('Payment Processor does not support refund');
    }
    $result = $processor->doRefund($params);
    return civicrm_api3_create_success([$result], $params);
  }
  
  This endpoint only get two params:
  
  payment_processor_id
  amount
  
  I guess, it's just a proof of concept because data are insufficient to create any transaction.
  Is there any implementations of it?
  
  **Tags:** api, payment-processor, refund
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2024-11-25. Score: 1
  
  I think matt spearheaded this feature, in any case, he's implemented it for stripe, here: <https://lab.civicrm.org/extensions/stripe/-/blob/master/CRM/Core/Payment/Stripe.php>
  
  That implementation looks like it's expecting a transaction id, which is usually exactly what you need (since that should be a unique identifier of the transaction and shared/stored with the payment processor).
  
  What you're seeing in the api3 endpoint is just some code that checks if the processor supports refunds, before passing through whatever parameters it got.
  
  TBH, I've avoided implementing it, due to the risk of bad things happening unintentionally.
  
  
  ---
  
  