Example #1
0
    def dispute_details_from_entity(
        self,
        dispute: Dispute,
        response_type: ResponseType = ResponseType.MINIMAL
    ) -> PaypalApiResponse[Dispute]:
        """Performs an API call to show the details for a dispute, by ID. 
        
        Arguments:
            dispute_id {str} -- Dispute identifier
        
        Keyword Arguments:
            response_type {ResponseType} -- The preferred response type (default: {ResponseType.MINIMAL})
        
        Returns:
            PaypalApiResponse[Dispute] -- [description]
        """
        url = dispute.read_link
        headers = {'Prefer': response_type.as_header_value()}
        api_response = self._execute_action_link(url, None, headers=headers)

        if api_response.status_code != 200:
            return PaypalApiResponse(True, api_response)

        return PaypalApiResponse(
            False, api_response,
            Dispute.serialize_from_json(api_response.json(), response_type))
Example #2
0
    def void_payment(self,
                     authorization_id: str,
                     auth_assertion_token: str = None) -> PaypalApiResponse:
        """Calls the paypal API to void an authorized payment, by ID. 
           See the api docs for a full set of rules.
        
        Arguments:
            authorization_id {str} -- The authorization id

        Keyword Arguments:
            auth_assertion_token {str} -- PayPal-Auth-Assertion see: https://developer.paypal.com/docs/api/payments/v2/docs/api/reference/api-requests/#paypal-auth-assertion (default: {None})
            
        Returns:
            PaypalApiResponse -- An api response with the authorization details.
        """
        api_response = None
        url = parse_url(self._base_url, authorization_id, 'void')

        if auth_assertion_token:
            api_response = self._session.post(
                url,
                None,
                headers={'PayPal-Auth-Assertion': auth_assertion_token})
        else:
            api_response = self._session.post(url, None)

        if api_response.status_code != 204:
            return PaypalApiResponse(True, api_response)

        return PaypalApiResponse(False, api_response)
Example #3
0
    def add_trackers(
        self,
        trackers: List[Tracker],
        response_type: ResponseType = ResponseType.MINIMAL
    ) -> PaypalApiResponse[Tracker]:
        """Adds trackers to a transaction
        
        Arguments:
            trackers {List[Tracker]} -- [description]
        
        Returns:
            PaypalApiResponse[Tracker] -- [description]
        """
        body = []
        url = parse_url(self._base_url, 'trackers-batch')
        headers = {'Prefer': response_type.as_header_value()}

        for t in trackers:
            b = t.to_dict()
            b['shipment_date'] = b.pop('_shipment_date', None)
            b['last_updated_time'] = b.pop('_last_updated_time', None)
            self._clean_dictionary(b, _TRACKER_PROPERTIES)
            body.append(b)

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

        if api_response.status_code != 200:
            return PaypalApiResponse(True, api_response)
        return PaypalApiResponse(
            False, api_response,
            Tracker.serialize_from_json(api_response.json(), response_type))
Example #4
0
    def show_tracking_info(
        self,
        transaction_id: str,
        tracking_number: int,
        response_type: ResponseType = ResponseType.MINIMAL
    ) -> PaypalApiResponse[Tracker]:
        """Gets the tracking info for a given tracker key
        
        Arguments:
            transaction_id {str} -- The id of the transaction
            tracking_number {int} -- The tracking number

        Keyword Arguments:
            response_type {ResponseType} -- [description] (default: {ResponseType.MINIMAL})
        
        Returns:
            PaypalApiResponse[Tracker] -- Response container with a Tracker instance including the required information
        """
        headers = {'Prefer': response_type.as_header_value()}
        url = parse_url(self._base_url, f'{transaction_id}-{tracking_number}')
        api_response = self._session.get(url, None, headers=headers)

        if api_response.status_code != 200:
            return PaypalApiResponse(True, api_response)
        return PaypalApiResponse(
            False, api_response,
            Tracker.serialize_from_json(api_response.json(), response_type))
Example #5
0
    def create_profile(
            self,
            profile: WebExpProfile,
            request_id: str = None) -> PaypalApiResponse[WebExpProfile]:
        """Calls the paypal Api to create a WebExp Profile
        
        Arguments:
            profile {WebExpProfile} -- The profile information.
        
        Keyword Arguments:
            request_id {str} -- Paypal request id for idempotency (default: {None})
        
        Returns:
            PaypalApiResponse[WebExpProfile] -- An api response with the profile
        """
        headers = {'PayPal-Request-Id': request_id} if request_id else dict()
        api_response = self._session.post(self._base_url,
                                          json.dumps(profile.to_dict()),
                                          headers=headers)

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

        return PaypalApiResponse(
            False, api_response,
            WebExpProfile.serialize_from_json(api_response.json()))
Example #6
0
    def capture_authorized_payment(
        self,
        authorization_id: str,
        invoice_id: str = None,
        note_to_payer: str = None,
        instruction: PaymentInstruction = None,
        amount: Money = None,
        final_capture: bool = False,
        request_id: str = None,
        response_type: ResponseType = ResponseType.MINIMAL
    ) -> PaypalApiResponse[Capture]:
        """Calls the paypal API to capture an authorized payment, by ID.
        
        Arguments:
            authorization_id {str} -- authorization id
            invoice_id {str} -- associated invoice
            note_to_payer {str} -- informational notes about the settlement. Appears in the payer's transaction history and received emails.
        
        Keyword Arguments:
            instruction {PaymentInstruction} -- Any additional payment instructions for PayPal for Partner customers (default: {None})
            amount {Money} -- The amount to capture. If none the full amount will be captured (default: {None}).
            final_capture {bool} -- dictates whether you can make additional captures against the authorized payment (default: {False}).
            request_id {str} -- Paypal request id for idempotence (default: {None})
            response_type {ResponseType} -- desired response type (default: {ResponseType.MINIMAL})
        
        Returns:
            PaypalApiResponse[Authorization] -- An api response with the authorization details
        """
        body = dict()
        url = parse_url(self._base_url, authorization_id, 'capture')
        headers = {'Prefer': response_type.as_header_value()}

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

        if invoice_id:
            body['invoice_id'] = invoice_id
        if note_to_payer:
            body['note_to_payer'] = note_to_payer
        if final_capture:
            body['final_capture'] = final_capture
        if instruction:
            body['instruction'] = instruction
        if amount:
            body['amount'] = amount.to_dict()

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

        if api_response.status_code != 201:
            return PaypalApiResponse(True, api_response)

        return PaypalApiResponse(
            False, api_response,
            Capture.serialize_from_json(api_response.json()))
Example #7
0
    def refund_capture(
        self,
        capture_id: str,
        invoice_id: str,
        note_to_payer: str,
        amount: Money = None,
        request_id: str = None,
        auth_assertion_token: str = None,
        response_type: ResponseType = ResponseType.MINIMAL
    ) -> PaypalApiResponse[Refund]:
        """Calls the api to refund a capture
        
        Arguments:
            capture_id {str} -- capture identifier
            invoice_id {str} -- invoice related capture
            note_to_payer {str} -- notes to the customer
        
        Keyword Arguments:
            amount {Money} -- amount to be refunded if None then 'captured amount - previous refunds' (default: {None})
            request_id {str} -- request id for idempotence (default: {None})
            auth_assertion_token {str} -- auth assertion token. See paypal header docs (default: {None})
            response_type {ResponseType} -- response type. See paypal header docs (default: {ResponseType.MINIMAL})
        
        Returns:
            PaypalApiResponse[Refund] -- api response with refund details
        """

        body = dict()
        url = parse_url(self._base_url, capture_id, 'refund')

        headers = {'Prefer': response_type.as_header_value()}

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

        if invoice_id:
            body['invoice_id'] = invoice_id
        if note_to_payer:
            body['note_to_payer'] = note_to_payer
        if amount:
            body['amount'] = amount.to_dict()

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

        if api_response.status_code != 201:
            return PaypalApiResponse(True, api_response)

        return PaypalApiResponse(
            False, api_response,
            Refund.serialize_from_json(api_response.json()))
Example #8
0
    def capture_payment_for_order(
        self,
        order_id: str,
        payment_source: PaymentSource = None,
        request_id: str = None,
        client_metadata_id: str = None,
        auth_assertion: str = None,
        response_type: ResponseType = ResponseType.MINIMAL
    ) -> PaypalApiResponse[Order]:
        """Calls the API to Capture a payment for an order. 
           To successfully authorize payment for an order, 
           the buyer must first approve the order 
           or a valid payment_source must be provided in the request.
        
        Arguments:
            order_id {str} -- The order id
        
        Keyword Arguments:
            payment_source {PaymentSource} -- Source of payment for the order if the user wasn't redirected in the order creation to approve the payment. (default: {None})
            request_id {str} -- Request id for idempotence (default: {None})
            client_metadata_id {str} -- Verifies that the payment originates from a valid, user-consented device and application. Must be included in order to be eligible for PayPal Seller Protection. (default: {None})
            auth_assertion {str} -- A JWT assertion that identifies the merchant (default: {None})
            response_type {ResponseType} --  (default: {ResponseType.MINIMAL})
        
        Returns:
            PaypalApiResponse[Order] -- API operation response with the order if successful
        """
        url = parse_url(self._base_url, order_id, 'capture')

        headers = {'Prefer': response_type.as_header_value()}

        if request_id:
            headers['PayPal-Request-Id'] = request_id
        if auth_assertion:
            headers['PayPal-Auth-Assertion'] = auth_assertion
        if client_metadata_id:
            headers['PayPal-Client-Metadata-Id'] = client_metadata_id

        if payment_source:
            api_response = self._session.post(url,
                                              json.dumps(
                                                  payment_source.to_dict()),
                                              headers=headers)
        else:
            api_response = self._session.post(url, None)

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

        return PaypalApiResponse(
            False, api_response,
            Order.serialize_from_json(api_response.json(), response_type))
Example #9
0
    def show_refund_details(self, refund_id: str) -> PaypalApiResponse[Refund]:
        """Calls the paypal API to show details for an authorized payment, by ID.
        
        Arguments:
            refund_id {str} -- The refund id
        
        Returns:
            PaypalApiResponse[Refund] -- An api response with the refund details
        """
        api_response = self._session.get(parse_url(self._base_url, refund_id))

        if api_response.status_code != 200:
            return PaypalApiResponse(True, api_response)

        return PaypalApiResponse(False, api_response, Refund.serialize_from_json(api_response.json()))
Example #10
0
    def update_tracking_info_by_entity(
            self, tracker: Tracker) -> PaypalApiResponse[Tracker]:
        """Updates tracking info in the api
        
        Arguments:
            transaction_id {str} -- The id of the transaction
            tracking_number {int} -- The tracking number

        Keyword Arguments:
            mappings with the fields to be updated, see the docs for the names & values.
        
        Returns:
            PaypalApiResponse[Tracker] -- Response container with the response status
        """
        body = tracker.json_data
        url = tracker.update_link

        for item in tracker.to_dict().items():
            key = item.key
            if key in body.keys():
                body[key] = item.value

        api_response = self._execute_action_link(url, body)
        error = api_response.status_code != 204
        return PaypalApiResponse(error, api_response)
Example #11
0
    def show_order_details(self, order_id: str) -> PaypalApiResponse[Order]:
        """Calls the api to retrieve the order details
        
        Arguments:
            order_id {str} -- The id of the order.
        
        Returns:
            PaypalApiResponse -- API operation response with the order if successful
        """
        api_response = self._session.get(parse_url(self._base_url, order_id))

        if api_response.status_code != 200:
            return PaypalApiResponse(True, api_response)

        return PaypalApiResponse(
            False, api_response,
            Order.serialize_from_json(api_response.json()))
Example #12
0
    def fully_update_profile(self, profile_id: str, name: str, temporary: bool,
                             flow_config: FlowConfig) -> PaypalApiResponse:
        """Calls the api to fully update a web experience profile, by ID.
        
        Arguments:
            profile_id {str} -- The profile id
            updates {List[PatchUpdateRequest]} -- list of update operations
        
        Returns:
            PaypalApiResponse -- API response status
        """
        url = parse_url(self._base_url, profile_id)
        body = WebExpProfile.create(name, temporary, flow_config)

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

        if api_response.status_code != 204:
            return PaypalApiResponse(True, api_response)
        return PaypalApiResponse(False, api_response)
Example #13
0
    def show_product_details(self, product_id: str, response_type = ResponseType.MINIMAL) -> PaypalApiResponse[Product]:
        """Calls the API to get the details for a given product
        
        Arguments:
            product_id {str} -- The product identifier
        
        Keyword Arguments:
            response_type {[type]} -- Response representation (default: {ResponseType.MINIMAL})
        
        Returns:
            PaypalApiResponse[Product] -- Response status with data
        """
        url = parse_url(self._base_url, product_id)
        headers = { 'Prefer': response_type.as_header_value() }        
        api_response = self._session.get(url, None, headers = headers)

        if api_response.status_code != 200:
            return PaypalApiResponse(True, api_response)

        return PaypalApiResponse(False, api_response, Product.serialize_from_json(api_response.json(), response_type))
Example #14
0
    def product_details_from_entity(self, product: Product, response_type: ResponseType=ResponseType.MINIMAL) -> PaypalApiResponse[Product]:
        """Calls the API to get the details for a given product
        
        Arguments:
            product {Product} -- The product entity with the HATEOAS link
        
        Keyword Arguments:
            response_type {[type]} -- Response representation (default: {ResponseType.MINIMAL})
        
        Returns:
            PaypalApiResponse[Product] -- Response status with data
        """
        url = product.read_link
        headers = { 'Prefer': response_type.as_header_value() }        
        api_response = self._session.get(url, None, headers = headers)

        if api_response.status_code != 200:
            return PaypalApiResponse(True, api_response)

        return PaypalApiResponse(False, api_response, Product.serialize_from_json(api_response.json(), response_type))
Example #15
0
    def create_product(self, product: Product, response_type: ResponseType = ResponseType.MINIMAL) -> PaypalApiResponse[Product]:
        """Performs an API call to create a new product
        
        Arguments:
            product_name {str} -- The product info
            product_type {ProductType} -- the response type (Minimal or Representation)
        """
        url = self._base_url
        headers = { 'Prefer': response_type.as_header_value() }
        
        body = product.to_dict()
        body['create_time'] = body.pop('_create_time', None)
        body['update_time'] = body.pop('_update_time', None)
        self._clean_dictionary(body, _PRODUCT_PROPERTIES)

        api_response = self._session.post(url, json.dumps(body), headers = headers)
        
        if api_response.status_code != 201:
            return PaypalApiResponse(True, api_response)
        return PaypalApiResponse(False, api_response, Product.serialize_from_json(api_response.json(), response_type))
Example #16
0
    def tracking_info_by_entity(
        self,
        tracker: Tracker,
        response_type: ResponseType = ResponseType.MINIMAL
    ) -> PaypalApiResponse[Tracker]:
        """Gets the tracking info for a given tracking entity
        
        Arguments:
            tracker {Tracker} -- a tracking entity
        
        Returns:
            PaypalApiResponse[Tracker] -- Response container with a Tracker instance including the required information
        """
        url = tracker.read_link
        headers = {'Prefer': response_type.as_header_value()}
        api_response = self._execute_action_link(url, None, headers=headers)

        if api_response.status_code != 200:
            return PaypalApiResponse(True, api_response)
        return PaypalApiResponse(
            False, api_response,
            Tracker.serialize_from_json(api_response.json(), response_type))
Example #17
0
    def create_order(
        self,
        order: Order,
        request_id: str = None,
        partner_attr_id: str = None,
        response_type: ResponseType = ResponseType.MINIMAL
    ) -> PaypalApiResponse[Order]:
        """Calls the paypal Api to create an order
        
        Arguments:
            order {Order} -- The order information.
        
        Keyword Arguments:
            request_id {str} -- Paypal request id for idempotency (default: {None})
            partner_attr_id {str} --  Identifies the caller as a PayPal partner. To receive revenue attribution. (default: {None})
            response_type {ResponseType} -- Response type to be handled (default: {ResponseType.MINIMAL})
        
        Returns:
            PaypalApiResponse[Order] -- An api response with the order
        """
        url = self._base_url

        headers = {'Prefer': response_type.as_header_value()}

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

        api_response = self._session.post(url,
                                          json.dumps(order.to_dict()),
                                          headers=headers)

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

        return PaypalApiResponse(
            False, api_response,
            Order.serialize_from_json(api_response.json(), response_type))
Example #18
0
    def path_update_profile(
            self, profile_id: str,
            updates: List[PatchUpdateRequest]) -> PaypalApiResponse:
        """Calls the api to partially-update a web experience profile, by ID.
        
        Arguments:
            profile_id {str} -- The profile id
            updates {List[PatchUpdateRequest]} -- list of update operations
        
        Returns:
            PaypalApiResponse -- API response status
        """
        url = parse_url(self._base_url, profile_id)
        body = json.dumps([{
            'op': x.operation,
            'path': x.path,
            'value': x.value
        } for x in updates])

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

        if api_response.status_code != 204:
            return PaypalApiResponse(True, api_response)
        return PaypalApiResponse(False, api_response)
Example #19
0
    def update_product(self, product_id: str, updates: List[ProductUpdateRequest]) -> PaypalApiResponse:
        """Updates a product
        
        Arguments:
            product_id {str} -- [description]
            updates {List[ProductUpdateRequest]} -- [description]
        
        Returns:
            PaypalApiResponse -- [description]
        """
        url = parse_url(self._base_url, product_id)
        body = [ {'op': x.operation, 'path': x.path, 'value': x.value} for x in updates ]
        api_response = self._session.patch(url, json.dumps(body))

        return PaypalApiResponse(api_response.status_code != 204, api_response)
Example #20
0
    def update_order(self, order_id: str,
                     updates: List[PatchUpdateRequest]) -> PaypalApiResponse:
        """Updates an order with the CREATED or APPROVED status.
        
        Arguments:
            order_id {str} -- The id of the order to be updated.
            updates {List[PatchUpdateRequest]} -- The updates to be made.
        
        Returns:
            PaypalApiResponse -- API operation response
        """
        url = parse_url(self._base_url, order_id)
        body = json.dumps([{
            'op': x.operation,
            'path': x.path,
            'value': x.value
        } for x in updates])

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

        if api_response.status_code != 204:
            return PaypalApiResponse(True, api_response)

        return PaypalApiResponse(False, api_response)
Example #21
0
    def reauthorize_payment(
        self,
        authorization_id: str,
        amount: Money,
        request_id: str = None,
        response_type: ResponseType = ResponseType.MINIMAL
    ) -> PaypalApiResponse[Authorization]:
        """Calls the paypal API to reauthorize an authorized payment, by ID. 
           See the api docs for a full set of rules.
        
        Arguments:
            authorization_id {str} -- The authorization id
            amount {Money} -- The amount to reauthorize for an authorized payment.
        Returns:
            PaypalApiResponse[Authorization] -- An api response with the authorization details
        """
        body = dict()
        url = parse_url(self._base_url, authorization_id, 'reauthorize')
        headers = {'Prefer': response_type.as_header_value()}

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

        if amount:
            body['amount'] = amount.to_dict()

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

        if api_response.status_code != 201:
            return PaypalApiResponse(True, api_response)

        return PaypalApiResponse(
            False, api_response,
            Authorization.serialize_from_json(api_response.json()))
Example #22
0
    def update_tracking_info(self, transaction_id: str, tracking_number: int,
                             **kwargs) -> PaypalApiResponse[Tracker]:
        """Updates tracking info in the api
        
        Arguments:
            transaction_id {str} -- The id of the transaction
            tracking_number {int} -- The tracking number

        Keyword Arguments:
            mappings with the fields to be updated, see the docs for the names & values.
        
        Returns:
            PaypalApiResponse[Tracker] -- Response container with the response status
        """
        url = parse_url(self._base_url, f'{transaction_id}-{tracking_number}')
        api_response = self._session.put(url, json.dumps(kwargs))
        error = api_response.status_code != 204

        return PaypalApiResponse(error, api_response)
Example #23
0
    def partial_dispute_update(
            self, dispute_id: str, update_request: DisputeUpdateRequest
    ) -> PaypalApiResponse[Dispute]:
        """Calls the Paypal API to  Partially update a dispute, by ID.            
            Right now it's only possible to update the communication_detail value.
        
        Arguments:
            dispute_id {str} -- The dispute identifier
            update_request {DisputeUpdateRequest} -- Update request with the details
        
        Returns:
            PaypalApiResponse[Dispute] -- Operation response status
        """
        url = parse_url(self._base_url, dispute_id)
        body = {
            'op': update_request.operation,
            'path': update_request.path,
            'value': update_request.value
        }

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

        return PaypalApiResponse(api_response.status_code != 204, api_response)