Пример #1
0
    def create_batch_payout(self, sender_batch_header: SenderBatchHeader, items: List[PayoutItem], request_id: str = None) -> PaypalApiResponse[PayoutHeader]:
        """Calls the paypal API to create a batch payout to one or more recipients
        
        Arguments:
            sender_batch_header {SenderBatchHeader} -- Sender-provided payout header for a payout request.
            items {List[PayoutItem]} -- A list of individual payout items.
        
        Keyword Arguments:
            request_id {str} -- Request id for idempotence (default: {None})
        
        Returns:
            PaypalApiResponse[PayoutHeader] -- A response with the generated header.
        """
        headers = dict()
        url = self._base_url

        if request_id:
            headers['PayPal-Request-Id'] = request_id
        
        body = json.dumps({ sender_batch_header.to_dict(), items.to_dict() })
        api_response = self._session.post(url, body, headers = headers) if headers else self._session.post(url, body)

        if api_response.status_code // 100 != 2:
            return PaypalApiResponse.error(api_response)

        j_data = api_response.json().get('batch_header')

        return PaypalApiResponse.success(api_response, PayoutHeader.serialize_from_json(j_data) if j_data else None)
Пример #2
0
    def update_subscription(
            self, subscription_id: str,
            update_request: List[PatchUpdateRequest]) -> PaypalApiResponse:
        """Patch request to update a subscription. See the docs for details 
        
        Arguments:
            subscription_id {str} -- id of the subscription to be updated.
            update_request {PatchUpdateRequest} -- request object with update info.
        
        Returns:
            PaypalApiResponse -- Response obj with operation status
        """
        url = parse_url(self._base_url, subscription_id)
        body = json.dumps([{
            'op': x.operation,
            'value': x.value,
            'path': x.path
        } for x in update_request])

        api_response = self._session.patch(url, body)

        if api_response.status_code // 100 != 2:
            return PaypalApiResponse.error(api_response)

        return PaypalApiResponse.success(api_response)
Пример #3
0
    def generate_qr_code(self,
                         invoice_id: str,
                         width: int = 500,
                         height: int = 500,
                         action: str = 'pay') -> PaypalApiResponse:
        """ Calls the paypal API to generate a QR code for an invoice. 
            The QR code is a PNG image in Base64-encoded format that corresponds to the invoice ID. 
            You can generate a QR code for an invoice and add it to a paper or PDF invoice. 
            When customers use their mobile devices to scan the QR code, they are redirected to the PayPal mobile payment flow where they can view the invoice and pay online with PayPal or a credit card.
            Before you get a QR code, you must create an invoice and send an invoice to move the invoice from a draft to payable state. 
            Do not include an email address if you do not want the invoice emailed.
        
        Arguments:
            invoice_id {str} -- existing invoice id
        
        Keyword Arguments:
            width {int} -- The width, in pixels, of the QR code image. Value is from 150 to 500 (default: {500})
            height {int} -- The height, in pixels, of the QR code image. Value is from 150 to 500 (default: {500})
            action {str} -- The type of URL for which to generate a QR code. Valid values are 'pay' and 'details'. (default: {'pay'})
        
        Returns:
            PaypalApiResponse -- Api operation response status containing the response
        """
        url = parse_url(self._base_url, 'invoices', invoice_id,
                        'generate-qr-code')
        body = json.dumps({'width': width, 'height': height, 'action': action})
        response = self._session.post(url, body)

        if response.status_code != 200:
            return PaypalApiResponse.error(response)

        return PaypalApiResponse.success(response)
Пример #4
0
    def simulate_webhook_event(
            self, webhook_id: str, url: str, event_type: str,
            resource_version: str) -> PaypalApiResponse[WebhookEvent]:
        """Calls the paypal API to send a webhook simulation
        
        Arguments:
            webhook_id {str} -- Webhook id, if ommited url is required
            url {str} -- endpoint url, if ommited id is required 
            event_type {str} -- The event name, one per request
            resource_version {str} -- event type version
        
        Returns:
            PaypalApiResponse[WebhookEvent] -- A response with the webhooks events.
        """
        body = {'event_type': event_type}

        if body['url'] != None:
            body['url'] = url
        if body['webhook_id'] != None:
            body['webhooks_id'] = webhook_id
        if body['resource_version'] != None:
            body['resource_version'] = resource_version

        api_response = self._session.post(self._base_url, json.dumps(body))

        if api_response.status_code // 100 != 2:
            return PaypalApiResponse.error(api_response)

        return PaypalApiResponse.success(
            api_response,
            WebhookEvent.serialize_from_json(api_response.json()))
Пример #5
0
    def update_quantity_in_subscription(
        self, subscription_id: str, update: SubscriptionQuantityUpdateRequest
    ) -> PaypalApiResponse[Subscription]:
        """Calls the paypal API to updates the quantity of the product or service in a subscription. 
           this method can also be used to to switch the plan and update the shipping_amount, 
           shipping_address values for the subscription. This type of update requires the buyer's consent.
        
        Arguments:
            subscription_id {str} -- the subscription id
            update {SubscriptionQuantityUpdateRequest} -- update request info.
        
        Returns:
            PaypalApiResponse[Subscription] -- Response status with subscription details
        """
        body = json.dumps(update.to_dict())
        url = parse_url(self._base_url, subscription_id, 'revise')

        api_response = self._session.post(url, body)

        if api_response.status_code // 100 != 2:
            return PaypalApiResponse.error(api_response)

        return PaypalApiResponse.success(
            api_response,
            Subscription.serialize_from_json(api_response.json()))
Пример #6
0
    def _execute_subscription_action(self,
                                     subscription_id: str,
                                     action_name: str,
                                     reason: str = None) -> PaypalApiResponse:
        """Executes a generic and simple subscription action call to the Paypal API
        
        Arguments:
            subscription_id {str} -- The subscription id
            action_name {str} -- API URL action name
        
        Keyword Arguments:
            reason {str} -- A comment or reason if needed (default: {None})
        
        Returns:
            PaypalApiResponse -- [description]
        """
        body = json.dumps({'reason': reason}) if reason else None
        url = parse_url(self._base_url, subscription_id, action_name)

        api_response = self._session.post(url, body)

        if api_response.status_code // 100 != 2:
            return PaypalApiResponse.error(api_response)

        return PaypalApiResponse.success(api_response)
Пример #7
0
    def create_subscription(
        self,
        subscription: Subscription,
        request_id: str = None,
        response_type: ResponseType = ResponseType.MINIMAL
    ) -> PaypalApiResponse[Subscription]:
        """Calls the paypal API to create a subscription
        
        Arguments:
            subscription {Subscription} -- The subscription to be made (use the create factory method)
        
        Keyword Arguments:
            request_id {str} -- Paypal request id for idempotence (default: {None})
            response_type {ResponseType} -- Peferred response type (default: {ResponseType.MINIMAL})
        
        Returns:
            PaypalApiResponse[Subscription] -- an API response object with the subscription info
        """
        url = self._base_url
        body = json.dumps(subscription.to_dict())
        headers = {'Prefer': response_type.as_header_value()}

        if request_id:
            headers['PayPal-Request-Id'] = request_id

        api_response = self._session.post(url, body, headers=headers)

        if api_response.status_code // 100 != 2:
            return PaypalApiResponse.error(api_response)

        return PaypalApiResponse.success(
            api_response,
            Subscription.serialize_from_json(api_response.json(),
                                             response_type))
Пример #8
0
    def record_invoice_refund(
            self, invoice_id: str,
            refund_detail: RefundDetail) -> PaypalApiResponse:
        """Calls the API to record a refund for the invoice.
           If all payments are refunded, the invoice is marked as REFUNDED. 
           Otherwise, the invoice is marked as PARTIALLY REFUNDED.
        
        Arguments:
            invoice_id {str} -- id of the invoice
            payment_detail {RefundDetail} -- payment details
        
        Returns:
            PaypalApiResponse -- Api operation response status containing the response
        """
        url = parse_url(self._base_url, 'invoices', invoice_id, 'refunds')
        body = json.dumps(
            {k: v
             for k, v in refund_detail.to_dict().items() if v != None})

        response = self._session.post(url, body)

        if response.status_code != 204:
            return PaypalApiResponse.error(response)

        return PaypalApiResponse.success(response)
Пример #9
0
    def resend_event_notification(
            self,
            event_id: str,
            webhooks_ids: List[str] = []) -> PaypalApiResponse[WebhookEvent]:
        """Calls the paypal API to resend notification events
        
        Arguments:
            event_id {str} -- The webhook event id
        
        Keyword Arguments:
            webhooks_ids {List[str]} -- webhooks notification to resend (all pending if empty) (default: {[]})
        
        Returns:
            PaypalApiResponse[WebhookEvent] -- A response with the webhooks events.
        """
        body = {'webhook_ids': webhooks_ids or []}
        api_response = self._session.post(parse_url(self._base_url, event_id),
                                          json.dumps(body))

        if api_response.status_code // 100 != 2:
            return PaypalApiResponse.error(api_response)

        return PaypalApiResponse.success(
            api_response,
            WebhookEvent.serialize_from_json(api_response.json()))
Пример #10
0
    def send_invoice(
            self,
            invoice_id: str,
            subject: str,
            note: str,
            send_to_invoicer: bool,
            send_to_recipient: bool,
            additional_recipients: List[str] = [],
            paypal_request_id: str = None) -> PaypalApiResponse[Invoice]:
        """Calls the paypal API to send or schedule an invoice, by ID, to be sent to a customer. The action depends on the invoice issue date:
            If the invoice issue date is current or in the past, sends the invoice immediately.
            If the invoice issue date is in the future, schedules the invoice to be sent on that date.
            To suppress the merchant's email notification, set the send_to_invoicer body parameter to false. 
            To send the invoice through a share link and not through PayPal, set the send_to_recipient parameter to false in the notification object. 
            The send_to_recipient parameter does not apply to a future issue date because the invoice is scheduled to be sent through PayPal on that date.
        
        Arguments:
            invoice_id {str} -- invoice id
            subject {str} --  The subject of the email that is sent as a notification to the recipient.
            note {str} -- A note to the payer.
            send_to_invoicer {bool} -- Indicates whether to send a copy of the email to the merchant.
            send_to_recipient {bool} -- Indicates whether to send a copy of the email to the recipient.

        Keyword Arguments:
            paypal_request_id {str} -- Paypal request id for idempotence. (default: {None})
            additional_recipients {List[str]} -- An array of one or more CC: emails to which notifications are sent. (default: {[]})

        Returns:
            PaypalApiResponse -- Api operation response status with parsed objects within
        """
        response = None
        url = parse_url(self._base_url, 'invoices', invoice_id, 'send')

        body = json.dumps({
            'subject': subject,
            'note': note,
            'send_to_invoicer': send_to_invoicer,
            'send_to_recipient': send_to_recipient
        })

        if additional_recipients:
            body['additional_recipients'] = [{
                'email_address': x
            } for x in additional_recipients]

        if paypal_request_id:
            response = self._session.post(
                url, body, headers={'PayPal-Request-Id': paypal_request_id})
        else:
            response = self._session.post(url, body)

        if response.status_code // 100 != 2:
            return PaypalApiResponse.error(response)

        if response.status_code == 200:
            return PaypalApiResponse.success(
                response, Invoice.serialize_from_json(response.json()))

        return PaypalApiResponse.success(response)
Пример #11
0
 def delete_template(self, template_id: str) -> PaypalApiResponse:
     """Deletes a template by id
     
     Arguments:
         template_id {str} -- The id of the template to be deleted
     
     Returns:
         PaypalApiResponse -- API Response.
     """
     response = self._session.delete(parse_url(self._base_url, template_id))
     return PaypalApiResponse.success(
         response
     ) if response.status_code == 204 else PaypalApiResponse.error(response)
Пример #12
0
    def show_payout_item_details(self, payout_item_id: str) -> PaypalApiResponse[PayoutItem]:
        """Calls the paypal API to show a payout item details
        
        Arguments:
            payout_item_id {str} -- Desired payout item id
        
        Returns:
            PaypalApiResponse[PayoutItem] -- Response with the item data if successful
        """        
        api_response = self._session.get(parse_url(self._base_url, payout_item_id))

        if api_response.status_code // 100 != 2:
            return PaypalApiResponse.error(api_response)

        return PaypalApiResponse.success(api_response, PayoutItem.serialize_from_json(api_response.json()))
Пример #13
0
    def _process_simple_response(self,
                                 api_response) -> PaypalApiResponse[Webhook]:
        """Process a simple webhook response
        
        Arguments:
            api_response {[type]} -- The http response obj from the request lib
        
        Returns:
            PaypalApiResponse[Webhook] -- Paypal response status with webhook object.
        """
        if api_response.status_code // 100 != 2:
            return PaypalApiResponse.error(api_response)

        return PaypalApiResponse.success(
            api_response, Webhook.serialize_from_json(api_response.json()))
Пример #14
0
 def delete_webhook(self, webhook_id: str) -> PaypalApiResponse:
     """Calls the paypal API to delete a webhook by id.
     
     Arguments:
         webhook_id {str} -- Id of the Webhook to be deleted. 
     
     Returns:
         PaypalApiResponse -- Paypal response status
     """
     api_response = self._session.delete(
         parse_url(self._base_url, webhook_id))
     return PaypalApiResponse.error(
         api_response
     ) if api_response.status_code // 100 != 2 else PaypalApiResponse.success(
         api_response)
Пример #15
0
    def create_draft_invoice(self, invoice: Invoice) -> PaypalApiResponse:
        """Calls the paypal API to generate an invoice draft.
        
        Arguments:            
            invoice {Invoice} -- the invoice information

        Returns:
            PaypalApiResponse -- The paypal API response
        """
        response = self._session.post(parse_url(self._base_url, 'invoices'),
                                      json.dumps(invoice.to_dict()))

        if response.status_code != 201:
            return PaypalApiResponse.error(response)

        return PaypalApiResponse.success(response)
Пример #16
0
    def show_payout_batch_details(
        self, payout_batch_id: str, page: int = 1, page_size: int = 1000, 
        fields: str = None, total_required: bool = True) -> PaypalApiResponse[PagedPayout]:
        
        url = parse_url(self._base_url, payout_batch_id)
        params = { 'page': page,  'page_size': page_size, 'total_required': total_required }

        if fields:
            params['fields'] = fields
        
        api_response = self._session.get(url, params)

        if api_response.status_code // 100 != 2:
            return PaypalApiResponse.error(api_response)

        return PaypalApiResponse.success(api_response, PagedPayout.serialize_from_json(api_response.json()))
Пример #17
0
    def show_template_details(self,
                              template_id: str) -> PaypalApiResponse[Template]:
        """Shows the details for a template by it's id
        
        Arguments:
            template_id {str} -- The template id
        
        Returns:
            PaypalApiResponse[Template] -- Response status with a Template object
        """
        response = self._session.get(parse_url(self._base_url, template_id))

        if response.status_code != 200:
            return PaypalApiResponse.error(response)

        return PaypalApiResponse.success(
            response, Invoice.serialize_from_json(response.json()))
Пример #18
0
    def send_invoice_reminder(
            self,
            invoice_id: str,
            subject: str,
            note: str,
            send_to_invoicer: bool,
            send_to_recipient: bool,
            additional_recipients: List[str] = []
    ) -> PaypalApiResponse[Invoice]:
        """Calls the paypal API to sends a reminder to the payer about an invoice, by ID. 
           In the JSON request body, include a notification object that defines the subject 
           of the reminder and other details. 
        
        Arguments:
            invoice_id {str} -- invoice id
            subject {str} --  The subject of the email that is sent as a notification to the recipient.
            note {str} -- A note to the payer.
            send_to_invoicer {bool} -- Indicates whether to send a copy of the email to the merchant.
            send_to_recipient {bool} -- Indicates whether to send a copy of the email to the recipient.
            additional_recipients {List[str]} -- An array of one or more CC: emails to which notifications are sent.
             If ignored, a notification is sent to all CC: email addresses that are part of the invoice.

        Returns:
            PaypalApiResponse -- Api operation response status with parsed objects within
        """
        url = parse_url(self._base_url, 'invoices', invoice_id, 'remind')

        body = json.dumps({
            'subject': subject,
            'note': note,
            'send_to_invoicer': send_to_invoicer,
            'send_to_recipient': send_to_recipient
        })

        if additional_recipients:
            body['additional_recipients'] = [{
                'email_address': x
            } for x in additional_recipients]

        response = self._session.post(url, body)

        if response.status_code != 204:
            return PaypalApiResponse.error(response)

        return PaypalApiResponse.success(response)
Пример #19
0
    def show_invoice_details(self,
                             invoice_id: str) -> PaypalApiResponse[Invoice]:
        """Calls the paypal API to show details for an invoice.
        
        Arguments:
            invoice_id {str} -- invoice id

        Returns:
            PaypalApiResponse -- Api operation response status with parsed objects within
        """
        response = self._session.get(
            parse_url(self._base_url, 'invoices', invoice_id))

        if response.status_code != 200:
            return PaypalApiResponse.error(response)

        return PaypalApiResponse.success(
            response, Invoice.serialize_from_json(response.json()))
Пример #20
0
    def show_event_notification_details(
            self, event_id: str) -> PaypalApiResponse[WebhookEvent]:
        """Calls the API to get the details for a webhook event notification.
        
        Arguments:
            event_id {str} -- The webhook notification event id
        
        Returns:
            PaypalApiResponse[WebhookEvent] -- Paypal response status with event obj.
        """
        api_response = self._session.get(parse_url(self._base_url, event_id))

        if api_response.status_code // 100 != 2:
            return PaypalApiResponse.error(api_response)

        return PaypalApiResponse.success(
            api_response,
            WebhookEvent.serialize_from_json(api_response.json()))
Пример #21
0
    def delete_external_refund(self, invoice_id: str,
                               transaction_id: str) -> PaypalApiResponse:
        """  Deletes an external refund, by invoice ID and transaction ID.
        
        Arguments:
            invoice_id {str} -- id of the invoice
            transaction_id {str} --  The ID of the external payment transaction to delete.
        
        Returns:
            PaypalApiResponse -- Api operation response status containing the response
        """
        response = self._session.delete(
            parse_url(self._base_url, 'invoices', invoice_id, 'refunds',
                      transaction_id))

        if response.status_code != 204:
            return PaypalApiResponse.error(response)

        return PaypalApiResponse.success(response)
Пример #22
0
    def show_subscription_details(
            self, subscription_id: str) -> PaypalApiResponse[Subscription]:
        """Calls the paypal API to get a subscription details
        
        Arguments:
            subscription_id {str} -- The subscription identifier
        
        Returns:
            PaypalApiResponse[Subscription] -- Api response obj with the subscription info.
        """
        api_response = self._session.get(
            parse_url(self._base_url, subscription_id))

        if api_response.status_code // 100 != 2:
            return PaypalApiResponse.error(api_response)

        return PaypalApiResponse.success(
            api_response,
            Subscription.serialize_from_json(api_response.json()))
Пример #23
0
    def cancel_unclaimed_payout_item(self, payout_item_id: str) -> PaypalApiResponse[PayoutItem]:
        """Calls the paypal API to cancel an unclaimed payout item details
        
        Arguments:
            payout_item_id {str} -- Desired payout item id
        
        Returns:
            PaypalApiResponse[PayoutItem] -- Response with the item data if successful
        """        
        api_response = self._session.post(parse_url(self._base_url, payout_item_id))

        if api_response.status_code // 100 != 2:
            return PaypalApiResponse.error(api_response)

        j_data = api_response.json()
        
        if j_data:
            PaypalApiResponse.success(api_response, PayoutItem.serialize_from_json(j_data))

        return PaypalApiResponse.success(api_response)
Пример #24
0
    def fully_update_invoice(
            self,
            invoice_id: str,
            invoice: Invoice,
            send_to_recipient: bool = True,
            send_to_invoicer: bool = True) -> PaypalApiResponse[Invoice]:
        """Calls the paypal API to fully update an invoice. This call does not support partial updates
        
        Arguments:
            invoice_id {str} -- invoice id
            invoice {Invoice} -- invoice with the updated info
        
        Keyword Arguments:
            send_to_recipient {bool} --  Indicates whether to send the invoice update notification to the recipient. (default: {True})
            send_to_invoicer {bool} --   Indicates whether to send the invoice update notification to the merchant. (default: {True})

        Returns:
            PaypalApiResponse -- Api operation response status with parsed objects within
        """
        params = {
            'send_to_recipient': send_to_recipient,
            'send_to_invoicer': send_to_invoicer
        }

        response = self._session.put(parse_url(self._base_url, 'invoices',
                                               invoice_id),
                                     json.dumps(invoice.to_dict()),
                                     params=params)

        # There seems to be a copy/paste mistake in the docs
        # It says no content but has a response within it.
        if response.status_code // 100 != 2:
            return PaypalApiResponse.error(response)

        json_response = response.json()

        if json_response:
            return PaypalApiResponse.success(
                response, Invoice.serialize_from_json(json_response))

        return PaypalApiResponse.success(response)
Пример #25
0
    def update_template(self, template_id: str,
                        template: Template) -> PaypalApiResponse[Template]:
        """Fully updates a template
        
        Arguments:
            template_id {str} -- the template id
            template {Template} -- template info with updates
        
        Returns:
            PaypalApiResponse[Template] -- A response that might contain the template
        """
        response = self._session.put(parse_url(self._base_url, template_id),
                                     json.dumps(template.to_dict()))

        # TODO: The docs are inconsistent on this call response. Test manually
        if response.status_code // 100 != 2:
            return PaypalApiResponse.error(response)

        parsed_data = Template.serialize_from_json(
            response.json()) if response.json() else None
        return PaypalApiResponse.success(response, parsed_data)
Пример #26
0
    def verify_webhook_signature(
            self, signature: WebhookSignature) -> SignatureVerificationStatus:
        """Calls the paypal API to verify a webhook signature (it usually comes in the headers).
        
        Arguments:
            signature {WebhookSignature} -- The signature
        
        Returns:
            SignatureVerificationStatus -- Verification status
        
        Raises:
            ApiCallError -- If there's an error calling the API.
        """
        api_response = self._session.post(self._base_url,
                                          json.dumps(signature.to_dict()))

        if api_response.status_code // 100 != 2:
            raise ApiCallError(PaypalApiResponse.error(api_response))

        return SignatureVerificationStatus[api_response.json().get(
            'verification_status')]
Пример #27
0
    def delete_invoice(self, invoice_id: str) -> PaypalApiResponse:
        """Calls the paypal API to delete a draft or scheduled invoice, by ID.
           only invoices in the draft or scheduled state can be deleted. 
           For invoices that have already been sent, you can cancel the invoice. 
           After you delete a draft or scheduled invoice, you can no longer use it 
           or show its details. However, its possible to reuse the invoice number.
        
        Arguments:
            invoice_id {str} -- invoice id

        Returns:
            PaypalApiResponse -- Api operation response status containing the response
        """

        response = self._session.delete(
            parse_url(self._base_url, 'invoices', invoice_id))

        if response.status_code != 204:
            return PaypalApiResponse.error(response)

        return PaypalApiResponse.success(response)
Пример #28
0
    def capture_authorized_payment_on_subscription(
            self,
            subscription_id: str,
            note: str,
            amount: Money,
            capture_type: str = 'OUTSTANDING_BALANCE',
            request_id: str = None) -> PaypalApiResponse[Capture]:
        """ Calls the Paypal API to perform a capture on an authorized payment 
            from the subscriber on the subscription.
        
        Arguments:
            subscription_id {str} -- the subscription id
            note {str} -- The reason or note for the subscription charge.
            amount {Money} -- The amount of the outstanding balance. Must not be greater than the current outstanding balance amount.
        
        Returns:
            PaypalApiResponse[Capture] -- A response with a capture
        """
        url = parse_url(self._base_url, subscription_id, 'capture')

        body = json.dumps({
            'note': note,
            'amount': amount.to_dict(),
            'capture_type': capture_type
        })

        if not request_id:
            api_response = self._session.post(url, body)
        else:
            api_response = self._session.post(
                url, body, headers={'PayPal-Request-Id': request_id})

        if api_response.status_code // 100 != 2:
            return PaypalApiResponse.error(api_response)

        j_data = api_response.json()
        return PaypalApiResponse.success(
            api_response,
            Capture.serialize_from_json(j_data) if j_data else None)
Пример #29
0
    def list_transactions(
        self,
        *,
        page: int = 1,
        page_size: int = 100,
        fields: Set[TransactionField] = {TransactionField.TRANSACTION_INFO},
        transaction_id: str = None,
        transaction_type: str = None,
        transaction_status: TransactionStatus = None,
        transaction_amount: AmountRange = None,
        date: DateRange = None,
        payment_instrument_type: PaymentInsrtumentType = None,
        store_id: str = None,
        terminal_id: str = None,
        balance_affecting_records_only: bool = True
    ) -> PaypalApiResponse[TransactionResponse]:
        """[summary]
        
        Keyword Arguments:
            page {int} -- Curent page (default: {1})
            page_size {int} -- page size max 500 (default: {100})
            fields {Set[TransactionField]} -- fields to include in the report (default: {{ TransactionField.TRANSACTION_INFO }})
            transaction_id {str} -- transaction ids (note: they are not unique) (default: {None})
            transaction_type {str} -- transaction event code (default: {None})
            transaction_status {TransactionStatus} -- transaction status for the query (default: {None})
            transaction_amount {AmountRange} -- transaction amount range filter (default: {None})
            date {DateRange} -- transaction date range filter (default: {None})
            payment_instrument_type {PaymentInsrtumentType} -- creditcard or debitcard payment (None for both) (default: {None})
            store_id {str} --  Filters the transactions in the response by a store ID.  (default: {None})
            terminal_id {str} -- Filters the transactions in the response by a terminal ID.  (default: {None})
            balance_affecting_records_only {bool} --  flag to include only balance-impacting or all transactions (default: {True})
        
        Returns:
            PaypalApiResponse[TransactionResponse] -- Page with all the desired transaction info
        """
        parameters = {
            'page': page,
            'store_id': store_id,
            'page_size': page_size,
            'terminal_id': terminal_id,
            'transaction_id': transaction_id,
            'transaction_type': transaction_type,
            'transaction_status': transaction_status,
            'balance_affecting_records_only': balance_affecting_records_only
        }

        parameters = {k: v for k, v in parameters.items() if v != None}

        if date:
            parameters['end_date'] = date.end
            parameters['start_date'] = date.start

        if payment_instrument_type:
            parameters[
                'payment_instrument_type'] = payment_instrument_type.name

        if transaction_amount:
            # Both currency codes should be equal in this request
            parameters[
                'transaction_currency'] = transaction_amount.lower_amount.currency_code
            parameters['transaction_amount'] = f'{transaction_amount.lower_amount} TO {transaction_amount.upper_amount}'\
                .replace('.', '')

        if fields:
            f = ','.join([x.as_parameter() for x in fields])
            if TransactionField.ALL in fields or len(fields) == 7:
                f = TransactionField.ALL.as_parameter()
            parameters['fields'] = f

        api_response = self._session.get(self._base_url, parameters)

        if api_response.status_code // 100 != 2:
            return PaypalApiResponse.error(api_response)

        return PaypalApiResponse.success(
            api_response,
            TransactionResponse.serialize_from_json(api_response.json()))