cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

Post request not working in CBO

Karan_Chopra_
Active Participant
0 Kudos
891

Hello Experts

We are trying to make a "Post" request in CBO but it is giving Error " Outbound call failed with status code 403, reason: Forbidden".

Get request is perfectly working and we are also getting X-CRSF token which is passed in post.

The same request is working in Postman and api hub. It is for API- /sap/opu/odata/sap/API_FCO_COST_RATE_SRV/A_ServiceCostRate.

https://api.sap.com/api/API_FCO_COST_RATE_SRV/tryout

We have maintained same technical user in communicatoin scenerios

DATA(lo_result) = write->get_root(<br>business_object_id = 'YY1_ICBILLING'<br>key = lv_key ).<br>DATA: lt_result         TYPE yy1_icbilling,<br>      ls_result         TYPE yy1_feedback_icbilling,<br>      lv_body           TYPE string,<br>      lv_costratefactor TYPE string,<br>      lv_msg            TYPE string.<br>FIELD-SYMBOLS: <ls_rate> TYPE yy1_feedback_icbilling.<br>TRY .<br>    cl_ble_trace_writer=>write_info_message( message = |Started | ).<br>    CHECK cl_ble_http_client=>is_service_available(<br>    communication_scenario = 'YY1_ICBILLING_SCENARIO'<br>    outbound_service = 'YY1_UPDATESERVICECOSTRATE_REST'<br>    ) = abap_true.<br>    cl_ble_trace_writer=>write_info_message( message = |Service Check successful| ).<br>    DATA(lo_client) = cl_ble_http_client=>create(<br>    communication_scenario = 'YY1_ICBILLING_SCENARIO'<br>    outbound_service = 'YY1_UPDATESERVICECOSTRATE_REST'<br>    ).<br>    cl_ble_trace_writer=>write_info_message( message = |Client created| ).<br>    DATA lv_request_body TYPE string.<br>* Creation of the service request<br>    DATA(request_get) = cl_ble_http_request=>create( ).<br>    DATA lv_s2 TYPE string VALUE '/API_FCO_COST_RATE_SRV/A_ServiceCostRate?$top=1'.<br>*/API_FCO_COST_RATE_SRV/A_ServiceCostRate<br>    cl_ble_trace_writer=>write_info_message( message = |Service created| ).<br>    "adding headers<br>    request_get->set_header_parameter( EXPORTING name = 'config_authType' value = 'Basic').<br>    request_get->set_header_parameter( EXPORTING name = 'Content-Type' value = 'application/json' ).<br>    request_get->set_header_parameter( EXPORTING name = 'Accept' value = '*/*' ).<br>    request_get->set_header_parameter( EXPORTING name = 'X-CSRF-TOKEN' value = 'FETCH' ).<br>    CONCATENATE lv_msg '/addedCSRF' INTO lv_msg.<br><br>    request_get->set_method( 'GET' )->set_resource_extension( lv_s2 ).<br>    CONCATENATE lv_msg '/setMethod' INTO lv_msg.<br><br>    DATA(response_get) = lo_client->send( request_get ).<br>    cl_ble_trace_writer=>write_info_message( message = |get request sent| ).<br>    DATA(lv_csrf) = response_get->get_header_parameter( 'x-csrf-token' ).<br>    cl_ble_trace_writer=>write_info_message( message = |CSRF Token: { lv_csrf }| ).<br>    SELECT * INTO TABLE @DATA(lt_rates) FROM yy1_feedback_icbilling WHERE reccompcode = @lv_key ORDER BY project.<br>    IF sy-subrc <> 0.<br>      cl_ble_trace_writer=>write_info_message( message = |No data for upload| ).<br>    ENDIF.<br>    DATA lv_s3 TYPE string VALUE '/API_FCO_COST_RATE_SRV/A_ServiceCostRate'.<br>* or add this to arrangemant path: API_FCO_COST_RATE_SRV/A_ServiceCostRate<br>    DATA(lo_client_post) = cl_ble_http_client=>create(<br>    communication_scenario = 'YY1_ICBILLING_SCENARIO'<br>    outbound_service = 'YY1_UPDATESERVICECOSTRATE_REST'<br>    ).<br>    DATA(request_post) = cl_ble_http_request=>create( ).<br>    request_post->set_header_parameter( EXPORTING name = 'Content-Type' value = 'application/json' ).<br>    request_post->set_header_parameter( EXPORTING name = 'Accept' value = '*/*' ).<br>    request_post->set_header_parameter( EXPORTING name = 'X-CSRF-TOKEN' value = lv_csrf ).<br><br>* request_post->set_method( 'POST' ). ""->set_resource_extension( lv_s2 ).<br>    request_post->set_method( 'POST' )->set_resource_extension( lv_s3 ).<br>    cl_ble_trace_writer=>write_info_message( message = |Post Set| ).<br>  CATCH cx_ble_http_exception INTO DATA(lx).<br>* The http status code can be checked.<br>    DATA lv_error TYPE string.<br>    lv_error = lx->status_code.<br>    CONCATENATE 'error ' lv_error INTO lv_msg.<br>    cl_ble_trace_writer=>write_info_message( message = |error:l { lv_msg }| ).<br>ENDTRY.<br>LOOP AT lt_rates ASSIGNING <ls_rate>.<br>  cl_ble_trace_writer=>write_info_message( message = |loop { sy-tabix }| ).<br>  lv_costratefactor = <ls_rate>-costratefactor.<br>  CONCATENATE '{"AccountingCostRateUUID": "01234567012345670123456701234567","CompanyCode":"' <ls_rate>-sendcompcode<br>  '","ReceivingCompanyCode"' <ls_rate>-reccompcode '","IsIntercompanyRate":true,'<br>* '"ActivityType":"' is not needed<br>  '","WBSElementExternalID":"' <ls_rate>-workpackage<br>  '","ValidityStartFiscalYearPeriod":"' <ls_rate>-validitystartperiod<br>  '","ValidityEndFiscalYearPeriod": "' <ls_rate>-validityendperiod<br>  '","Currency":"' <ls_rate>-currency<br>  '","CostRateVarblAmount":"' <ls_rate>-costrate<br>  '","CostRateScaleFactor": "' lv_costratefactor<br>  '","CostCtrActivityTypeQtyUnit":"' <ls_rate>-unit<br>  '","CostRateIsOverwriteMode": true}'<br>  INTO lv_body.<br>  cl_ble_trace_writer=>write_info_message( message = |body created| ).<br>  TRY.<br>      request_post->set_body(<br>      EXPORTING<br>      data = lv_body<br>      ).<br>      cl_ble_trace_writer=>write_info_message( message = |body set: { lv_body }| ).<br>      cl_ble_trace_writer=>write_info_message( message = |WP: { <ls_rate>-workpackage }| ).<br>      cl_ble_trace_writer=>write_info_message( message = |receiving: { <ls_rate>-reccompcode }| ).<br>      cl_ble_trace_writer=>write_info_message( message = |sending: { <ls_rate>-sendcompcode }| ).<br>      DATA(response_post) = lo_client_post->send( request_post ). ##########- ERROR at this call-#################<br>* DATA(response_post) = lo_client->send( request_post ).<br>      cl_ble_trace_writer=>write_info_message( message = |send: | ).<br>* Get the body of the response.<br>      DATA(lv_response_body) = response_post->get_body( ).<br>      cl_ble_trace_writer=>write_info_message( message = |Response body: { lv_response_body }| ).<br>      "ls_result = VALUE #( Parameters = substring( val = lv_body off = 500 len = 500 ) ).<br>    CATCH cx_ble_http_exception INTO DATA(lx_response).<br>* The http status code can be checked.<br>      DATA lv_error_resp TYPE string.<br>* lv_error_resp = lx_response->status_code.<br>* concatenate 'error ' lv_error_resp into lv_msg.<br>      lv_msg = lx_response->get_longtext( ).<br>* concatenate lv_error_resp into lv_msg.<br>      cl_ble_trace_writer=>write_info_message( message = |E { lv_msg }| ).<br>  ENDTRY.<br>  IF sy-tabix > 10.<br>    EXIT.<br>  ENDIF.<br>ENDLOOP.

Accepted Solutions (1)

Accepted Solutions (1)

Tayane
Product and Topic Expert
Product and Topic Expert
0 Kudos

Dear Karan,

After checking the thread updates, I noticed that you're still getting the error.

I suggest that you create an inicident for SAP Support investigate the issue.

Kind regards.

Answers (2)

Answers (2)

daviddasilva
Active Contributor
0 Kudos

Hi Karan,

It looks like you are trying to do the correct thing so its likely something small has gone wrong and it is hard to see.

Can you try a connectivity trace in S4 to try and review the request and that way you can inspect it to determine if any headers are missing etc.

403 means forbidden, so login is working ok, but authorization isn't. Can you double check the POST URL as there could be a typo or it's calling the wrong API maybe.

Hopefully the connectivity trace will shed some light on the root cause of your issue.

Kind regards,

David

Karan_Chopra_
Active Participant
0 Kudos

Hello David

Yes in connectivity trace I see Error with POST call but not with GET.

Do you know in that case what are the further steps?

PrasanthPadmanabhan
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi Karan,

Have you refered to the example https://help.sap.com/docs/SAP_S4HANA_CLOUD/0f69f8fb28ac4bf48d2b57b9637e81fa/24ec15cdc30c4d37afe33be4... , where a business object is updated via an oData call?

Best Regards,

Prasanth

Karan_Chopra_
Active Participant
0 Kudos

Hi Prasanth

Here we are calling POST for API Service Cost Rate

https://api.sap.com/api/API_FCO_COST_RATE_SRV/tryout

PrasanthPadmanabhan
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi Karan,

The blog https://blogs.sap.com/2018/06/13/mass-update-using-sap-s4hana-cloud-in-app-extensibility/ explains how to call a post API from a Custom Business Object. This should help to solve your issue

Best Regards,

Prasanth

Karan_Chopra_
Active Participant
0 Kudos

Hi Prasanth

We are doing exactly same approach as mentioned in blog but somehow POST is not working for us and giving forbidden error