5

I am attempting to integrate Paypal into an R Shiny app. I've been successful at setting up the sandbox and confirming payment. However, I can't quite figure out how to get the app to either download a csv file immediately or show a new button after successful payment to allow a download. Basically, I want to charge a cheap amount per download of my cleaned dataset as a csv. Here are the ui/server parts, including some of the reactive things I've tried (I've been trying to use shinyJS to get around it to no avail).

#ui
fluidRow(
        column(width = 12,
               boxPlus(
                 title = 'Bulk Financial Download - By Ticker',
                 closable = FALSE,
                 width = 12,
                 status = "info",
                 solidHeader = FALSE,
                 collapsible = TRUE,
                 enable_dropdown = FALSE,
                 fluidRow(
                   column(width = 3,
                 actionButton("Calculate", 
                              label = ui <- fluidPage(
                                tags$script(src = "https://www.paypalobjects.com/api/checkout.js "),
                                tags$script("paypal.Button.render({
                                // Configure environment
                                env: 'sandbox',
                                client: {
                                sandbox: 'hidden',
                                production: 'demo_production_client_id'
                                },
                                // Customize button (optional)
                                locale: 'en_US',
                                style: {
                                size: 'small',
                                color: 'gold',
                                shape: 'pill',
                                },
                                // Set up a payment
                                payment: function (data, actions) {
                                return actions.payment.create({
                                transactions: [{
                                amount: {
                                total: '0.01',
                                currency: 'USD'
                                }
                                }]
                                });
                                },
                                // Execute the payment
                                onAuthorize: function (data, actions) {
                                return actions.payment.execute()
                                .then(function () {
                                // Show a confirmation message to the buyer
                                window.alert('Thank you for your purchase!');
                                });
                                }
                                }, '#Calculate');"),
                                tags$div(id = "Calculate")))
                 ),
                 column(
                   width =3,
                 hidden(div(
                   id='actions',
                 downloadButton("downloadData", "Download")
                 ))
                 )
                 )
               )
               )
      )
#server
    shinyjs::hide('actions')


    observeEvent(input$Calculate, {
      shinyjs::hide('Calculate')
      shinyjs::show('actions')
    })

    observeEvent(input$ticker, {

      shinyjs::hide('actions')
      shinyjs::show('Calculate')
    })

     output$downloadData <- downloadHandler(
    filename = function() {
      paste(stockInfo()$symbol, "financials.csv", sep = "")
    },
    content = function(file) {
      write.csv(tables(), file, row.names = FALSE)
    }
  )

In my attempts so far, what happens is that there is a button around the Paypal button that activates the shinyjs show or hide, but nothing happens when I directly click the Paypal button beyond actually paying. I am also using shinydashboard and shinydashboardPlus.

bdavis562002
  • 101
  • 3
  • I would presume one way to go would be to put a custom message in the onAuthorize callback function. Then, have Shiny listen to that and if successful, use a RenderUI or conditional to show a download button. But really it would be great if someone could figure out a complete solution! – dca Aug 04 '20 at 21:02

1 Answers1

0

I had a somewhat similar challenge, wanting a part of my shiny app to react to a successful paypal payment. I found my solution here:

https://shiny.rstudio.com/articles/communicating-with-js.html

In my UI where I include the code to add the PayPal checkout button I added an additional line using the 'setInputValue' function:

window.alert('Thank you for your purchase!');
Shiny.setInputValue('payment', 'success');

Then on the Server side, I used an event observer to display one of two possible outputs:

  observeEvent(input$payment,{
      if(input$payment!='success'){
        output$mymap <- renderLeaflet({
          Option A
        })
       } else if(input$payment=='success'){
        output$mymap <- renderLeaflet({
          Option B
        })
      }
   })
  • I am also looking for a solution to this problem. I like this solution but I am concerned that it is insecure. Wouldn't it be straightforward for someone with a knowledge of JS to invoke the Shiny.setInputValue('payment', 'success'); line without paying? I don't have much knowledge of JS so I may be wrong. – TheDza Jun 25 '23 at 18:22